paint-brush
Async vs Sync Benchmark (.NET): Az aszinkron és a szinkron módszerek közötti különbségáltal@artemmikulich
1,873 olvasmányok
1,873 olvasmányok

Async vs Sync Benchmark (.NET): Az aszinkron és a szinkron módszerek közötti különbség

által Artem Mikulich5m2024/09/21
Read on Terminal Reader

Túl hosszú; Olvasni

Ez a cikk bemutatja az aszinkron és a szinkron módszerek közötti különbséget a gyakorlatban. Két független sáska-példány fut két gépen. A felhasználók száma egyenletesen növekszik a célszámig (*Felhasználók száma*). A növekedés sebességét egy * Spawn Rate* paraméter szabályozza (másodpercenként csatlakozó egyedi felhasználók száma)
featured image - Async vs Sync Benchmark (.NET): Az aszinkron és a szinkron módszerek közötti különbség
Artem Mikulich HackerNoon profile picture

Az egyik kedvenc interjúkérdésem: „Mit mondanak neked az olyan szavak, mint az async és a wait ?” mert ez lehetőséget ad egy érdekes beszélgetésre egy interjúalannyal… Vagy nem, mert lebegnek ebben a témában. Véleményem szerint drasztikusan fontos megérteni, miért használjuk ezt a technikát.


Úgy érzem, sok fejlesztő szívesebben hagyatkozik az „ez a legjobb gyakorlat” kijelentésre, és vakon használ aszinkron módszereket.


Ez a cikk bemutatja az aszinkron és a szinkron módszerek közötti különbséget a gyakorlatban.

Eszközök

  • .NET Web API alkalmazás (teszt cél)


  • 2 Azure SQL Databases


  • 2 Azure App Service Windows rendszeren (az alkalmazást tárolja)


  • Azure App Insights (mérőszámok gyűjtéséhez)


  • sáska keretrendszer (a felhasználói terhelés szimulálására).

Konfiguráció

Kísérleti séma

A benchmarkot a következő módon fogom lefuttatni. Két független sáska-példány fut két gépen. A Locust példányok olyan felhasználót szimulálnak, aki a következőket teszi:

  • Az 1. sáskahoszt felhasználója eléri az 1. App Service szinkron végpontját , megkapja a választ, és 0,5–1 másodpercig tétlen marad (a pontos késleltetés véletlenszerű). Ismétlés a kísérlet végéig.


  • A 2-es sáskahoszt felhasználója pontosan ugyanúgy viselkedik, egyetlen különbséggel – eléri az App Service 2 aszinkron végpontját .


A motorháztető alatt minden App Service csatlakozik a saját adatbázisához, és végrehajt egy SELECT lekérdezést, amely öt másodpercig tart, és néhány adatsort ad vissza. Lásd alább a vezérlő kódját a hivatkozásokért. Dapperrel hívom fel az adatbázist. Szeretném felhívni a figyelmet arra, hogy az aszinkron végpont aszinkron módon is hívja az adatbázist ( QueryAsync<T> ).


App Services kód


Érdemes hozzátenni, hogy ugyanazt a kódot telepítem mindkét alkalmazásszolgáltatásra.


A teszt során a felhasználók száma egyenletesen nő a célszámra ( Users Number ). A növekedés sebességét a Spawn Rate paraméter szabályozza (másodpercenként csatlakozó egyedi felhasználók száma) – minél nagyobb ez a szám, annál gyorsabban kerülnek hozzáadásra a felhasználók. A megjelenési sebesség 10 felhasználó/s minden kísérletnél.


Minden kísérlet 15 percre korlátozódik.


A gép konfigurációs részleteit a cikk Műszaki részletek szakaszában találja.

Mérések

  • kérések percenként – megmutatja azoknak a kéréseknek a számát, amelyeket az alkalmazás ténylegesen feldolgozott, és állapotkódot adott vissza.
  • szálak száma – az alkalmazásszolgáltatás által felhasznált szálak számát mutatja.
  • medián válaszidő, ms


A piros vonalak az aszinkron, a kék vonalak pedig a szinkron végpontra utalnak.


Ennyit az elméletről. Kezdjük.

1. kísérlet

  • felhasználók száma : 75 (szolgáltatásonként)


Láthatjuk, hogy mindkét végpont hasonlóan teljesít – percenként körülbelül 750 kérést kezel, 5200 ms medián válaszidővel.


1. kísérlet. Kérések percenként


Ebben a kísérletben a leglenyűgözőbb grafikon egy száltrend. A szinkron végpontnál lényegesen magasabb számokat láthat (kék grafikon) – több mint 100 szál!


1. kísérlet. Szálak száma


Ez azonban várható, és megfelel az elméletnek – amikor beérkezik egy kérés, és az alkalmazás felhívja az adatbázist, a szál blokkolva lesz, mert meg kell várnia a körút befejezését. Ezért amikor újabb kérés érkezik, az alkalmazásnak új szálat kell létrehoznia a kezeléséhez.


A piros grafikon – az aszinkron végponti szálak száma – eltérő viselkedést bizonyít. Amikor beérkezik egy kérés, és az alkalmazás felhívja az adatbázist, a szál blokkolása helyett visszatér egy szálkészletbe. Ezért, amikor újabb kérés érkezik, ez az ingyenes szál újrafelhasználásra kerül. Annak ellenére, hogy a bejövő kérések száma növekszik, az alkalmazás nem igényel új szálakat, így azok száma változatlan marad.


Érdemes megemlíteni a 3. mérőszámot – a medián válaszidőt . Mindkét végpont ugyanazt az eredményt mutatta – 5200 ms. Tehát teljesítményben nincs különbség.


1. kísérlet. Összegzés


Most itt az ideje felhúzni a tétet.

2. kísérlet

  • felhasználók száma : 150


Megdupláztuk a terhelést. Az aszinkron végpont sikeresen kezeli ezt a feladatot – percenkénti kérése 1500 körül mozog. A szinkron testvér végül elérte a hasonló számot, 1410-et. De ha megnézi az alábbi grafikont, látni fogja, hogy 10 percig tartott!


Ennek az az oka, hogy a szinkron végpont egy új felhasználó érkezésére egy másik szál létrehozásával reagál, de a felhasználókat gyorsabban adják hozzá a rendszerhez (csak emlékeztetve arra, hogy a Spawn Rate 10 felhasználó/s), mint ahogy a webszerver alkalmazkodni tud. Ez az oka annak, hogy a kezdet kezdetén sok kérést állított sorba.


2. kísérlet. Kérések percenként


Nem meglepő módon a szálszám mutatója továbbra is 34 körül van az aszinkron végpontnál, míg a szinkronnál 102-ről 155-re nőtt. A medián válaszidő a percenkénti kérés sebességéhez hasonlóan csökkent – a szinkron válaszidő sokkal magasabb volt a kísérlet elején. Ha 24 órán keresztül megtartottam volna a tesztet, a medián számok párosak lettek volna.


2. kísérlet. Összegzés


3. kísérlet

  • felhasználók száma : 200


A harmadik kísérlet célja a második során feltárt trendek bizonyítása – a szinkron végpont további romlása látható.


3. kísérlet. Összegzés


Következtetés

A szinkron műveletek helyett aszinkron használata nem javítja közvetlenül a teljesítményt vagy a felhasználói élményt. Először is növeli a stabilitást és a kiszámíthatóságot nyomás alatt. Más szavakkal, megemeli a terhelési küszöböt, így a rendszer többet tud feldolgozni, mielőtt leromlik.

Függelék #1. Műszaki részletek

  • Azure App Service: B1, 100 ACU , 1,75 Gb memória, A sorozatú számítási megfelelője.
  • Azure SQL Database: Standard S4: 200 DTU, 500 Mb tárhely.
  • SQL kapcsolat beállításai: Max Pool Size=200.

2. számú melléklet. Megjegyzések

A legtisztább teszteredmény eléréséhez teszteket kellett volna futtatnom 2 virtuális gépről, amelyek ugyanabban a hálózatban találhatók, ahol a cél App Services található.


Feltételeztem azonban, hogy a hálózati késés többé-kevésbé hasonló módon hat mindkét alkalmazásra. Ezért nem veszélyeztetheti a fő célt – az aszinkron és a szinkron módszerek viselkedésének összehasonlítását.

3. számú melléklet. Bónusz kísérlet

Mit törtem fel, hogy a szinkron végpontot majdnem ugyanolyan aszinkron működésre kényszerítsem, és ábrázoljam az alábbi grafikont (a kísérlet feltételei ugyanazok, mint a harmadiknál – 200 felhasználó)?


Bónusz kísérlet. Kérések percenként