Címke: JMeter

  • JMeter – 50.000 virtuális user

    JMeter – 50.000 virtuális user

    Megkérdeztem a Gemini-t, hogy megoldható-e, és ha igen, hogyan egy 50.000 useres performancia tesztelés az Apache JMeter-rel. A válasz itt következik:

    Igen, teljesen megoldható, de van egy kritikus technikai feltétel: egyetlen gépről (például egy laptopról vagy egyetlen virtuális gépről) nem lehet elindítani 50 000 egyidejű felhasználót, mert a hardveres korlátok (CPU, RAM, hálózati socketek kimerülése) miatt maga a tesztelő eszköz fog összeomlani. Ehhez elosztott (distributed) architektúrára vagy felhőalapú futtatásra lesz szükség.

    Így kezdenék neki lépésről lépésre:

    1. Célok és workload modell tisztázása

    • Pontosan mit jelent az 50 000 user? 50 000 egyidejűleg aktív felhasználó, akik folyamatosan kattintgatnak, vagy 50 000 egyidejű kapcsolat (session), de az aktivitásuk eloszlik?
    • Milyen a felhasználói útvonal (User Journey)? Nem mindegy, hogy csak a főoldalt hívják le (ez könnyű), vagy bejelentkeznek, keresnek, terméket raknak a kosárba és fizetnek (ez bonyolultabb, adatbázis- és tranzakcióigényes).
    • Milyen mérőszámokat vársz el? (pl. 95%-os válaszidő 2 másodperc alatt, 0% hibaarány mellett).

    2. A tesztinfrastruktúra felépítése (Distributed JMeter)

    Mivel egy átlagos JMeter worker gép maximum 1000–2000 szálat bír stabilan, 50 000 userhez 25-50 darab worker gépre lesz szükség:

    • Master-Worker (Slave) felállás: Egy központi JMeter Master irányítja a tesztet, és gyűjti az adatokat a worker gépekről (ezek lehetnek olcsó AWS EC2 instance-ok vagy Docker konténerek).
    • Alternatíva: Használhatsz dedikált terheléses felhőszolgáltatásokat is (pl. BlazeMeter), amelyek mögött ugyanez az elv fut, de nem kell manuálisan menedzselni a 30-40 szervert.

    3. A JMeter script megírása

    • Thread Group beállítások: A 50 000 szálat érdemes fokozatosan ráengedni a rendszerre (Ramp-up period, pl. 30–45 perc alatt), hogy látsd, hol kezd el lassulni a rendszer.
    • Valósághű viselkedés: Használj Think Time-ot (szüneteket a kérések között), különben a szkript robotként viselkedik, amit egy WAF (Web Application Firewall) vagy cache réteg azonnal blokkolhat.
    • Dinamikus adatok:CSV Data Set Config segítségével biztosítsd, hogy a felhasználók különböző nevekkel, jelszódal vagy tokenekkel jelentkezzenek be, ne ugyanazzal az egy fiókkal indítsa mind az 50k szál a kérést.

    4. Szerveroldali monitorozás bekötése (Monitoring)

    A JMeter csak azt mutatja meg, mit tapasztal a felhasználó (válaszidő, hiba), azt nem, hogy miért lassult be a szerver. Ehhez kell a backend monitoring:

    • Alkalmazásszerverek, adatbázisok, cache (Redis) CPU, RAM és I/O terhelésének figyelése (pl. Prometheus + Grafana vagy Datadog).
    • Adatbázis lassan futó lekérdezéseinek és connection pool telítettségének mérése.

    5. Tesztfutás és finomhangolás

    • Soha ne használd a JMeter GUI-t (grafikus felületet) terheléses teszt alatt! Csak parancssorból, non-gui módban futtasd a master gépet.
    • Fokozatosság elve: Ne 50 000 userrel kezdd. Először futtass le egy 1000 useres tesztet, javítsd ki az azonnal előjövő hibákat, majd skálázd fel 5000-re, 10 000-re, és így tovább, ambron eléred a célt.

    Milyen típusú rendszert (pl. webshop, REST API, banki backend) kell tesztelni, és milyen környezetben fut jelenleg?

    Egy REST API terheléses tesztelése 50 000 felhasználóval specifikus technikai kihívásokat rejt, amelyekre különösen figyelned kell a JMeter konfigurálása során:

    1. Hitelesítés és token-kezelés (Authentication)

    A REST API-k túlnyomó többsége token alapú (JWT vagy OAuth2).

    • Ne kérj le tokent minden egyes kérésnél: Ha mind az 50 000 szál a POST /api/login végponttal kezdi a tesztet, azzal azonnal túlterheled a hitelesítőszervert, még mielőtt a valódi API funkciókat tesztelnéd.
    • Megoldás: Előre generálj le egy token-készletet (pl. egy külön scripttel vagy adatbázis-lekérdezéssel), töltsd be egy CSV fájlba, és a JMeterben ezt olvastasd be. Így a felhasználók már eleve érvényes tokenekkel küldhetik a kéréseket.

    2. HTTP Request Defaults és Keep-Alive

    Magas koncurrencia esetén kritikus a hálózati kapcsolatok hatékonysága:

    • HTTP Request Defaults: Állítsd be a központi URL-t, portot és a Content-Type-ot (application/json), hogy ne kelljen minden egyes kérésnél megismételni.
    • Keep-Alive: A JMeter alapértelmezésben engedélyezi a Keep-Alive-ot. REST API-knál ez elengedhetetlen, mert így nem nyit és zár le TCP kapcsolatot minden egyes apró API híváshoz, ami drasztikusan csökkenti a hálózati terhelést a kliens oldalon, és valósághűbb képet ad a szerver teljesítményéről.

    3. Dinamikus adatok és JSON Extractor

    Egy REST API láncolt hívásokból áll (pl. létrehozol egy erőforrást POST-tal, majd annak az ID-jét lekéred GET-tel).

    • Használj JSON Extractor elemet a válaszokból (pl. létrehozott objektum ID-je, státusza) való adatkigyűjtésre.
    • Ezeket az értékeket mentsd el JMeter változókba (${id}), hogy a következő kérésben dinamikusan fel tudd használni.

    4. Payload (Adatcsomag) optimalizálás

    • Ha a tesztben nagy JSON payloadokat küldesz (pl. tömeges adatfeltöltés), kerüld a bonyolult, dinamikusan generált szövegeket a JMeter belső függvényeivel, mert az leterheli a JMeter saját CPU-ját.
    • A tesztadatokat (JSON törzseket) előre generált fájlokból (CSV vagy JSON file) olvasd be, így a worker gépek erőforrásai tisztán a hálózati kérésekre fognak fókuszálni.

    5. Válaszidő és aszinkronitás

    • Határozd meg, hogy az API-n belül vannak-e aszinkron műveletek (pl. üzenetssorba, RabbitMQ-ba vagy Kafka-ba küldött események). Ha igen, a válaszidő alacsony lehet (mert a szerver csak átvette az üzenetet), de a valódi feldolgozást a háttérben lévő worker service-eknek kell bírniuk, így a monitoringot kötelező kiterjeszteni a háttérfolyamatokra is.

    Szerintem elég jól megválaszolta a kérdést. Egy részével tisztában voltam, sejtettem, de akadt jó pár jó tanács is. Gondoltam megkérdezem, hogy JMeteren kívül milyen mást eszközt ajánlana ehhez.

    Ha a JMeter elosztott architektúrájának (a 25-50 worker gépnek a) manuális konfigurálása és karbantartása túl bonyolultnak tűnik, a modern teljesítménytesztelő eszköztárban kifejezetten REST API-khoz sokkal gördülékenyebb megoldások is léteznek:

    1. k6 (Grafana k6) – A legjobb választás REST API-khoz

    A k6 jelenleg a legnépszerűbb fejlesztőbarát alternatíva. C-ben íródott (Go runtime-mal), így nagyságrendekkel kevesebb memóriát és CPU-t fogyaszt, mint a Java-alapú JMeter.

    • Miért ideális 50k userhez? Egyetlen erősebb szerverről lényegesen több szálat (virtuális usert) tud futtatni, mint a JMeter, így kevesebb infrastruktúrára lesz szükséged.
    • Szkriptelés: JavaScriptben írod a teszteket, ami nagyon természetes a REST API JSON válaszok és dinamikus tokenek kezelésénél.
    • Integráció: Kiemelkedően jó Grafana, Prometheus és CI/CD (GitHub Actions, GitLab) támogatása van.

    2. Gatling – Ha elképesztő skálázhatóságra és szép riportokra van szükség

    A Gatling aszinkron (Netty-alapú) architektúrát használ, így nem rendel egy külön operációs rendszer szálat minden egyes felhasználóhoz.

    • Miért ideális 50k userhez? Brutálisan jó az erőforrás-kihasználása. Egyetlen közepes gépről képes több tízezer egyidejű kapcsolatot felépíteni és kezelni.
    • Szkriptelés: Scala, Java vagy Kotlin nyelven írhatsz szép, olvasható domain-specifikus kódot (DSL).
    • Riportok: Alapból nagyon részletes és vizuálisan tetszetős HTML riportokat generál a teszt végén.

    3. Locust – Ha Python-alapú veremből dolgozol

    A Locust egy nyílt forráskódú, Python-alapú tesztelőeszköz, ahol a felhasználói viselkedést tiszta Python kódban definiálod.

    • Miért ideális 50k userhez? Nagyon egyszerűen összefűzhető elosztott (distributed) módba (Master-Worker architektúra), és menet közben, a böngészős UI-ról is állítható a terhelés mértéke.
    • Előny: Ha a csapat már ismeri a Pythont, a tesztek megírása és karbantartása minimális időt vesz igénybe.

    Menedzselt felhős alternatívák (SaaS)

    Ha egyáltalán nem szeretnél szervereket bérelni és konfigurálni:

    • Grafana Cloud k6 / BlazeMeter / Loader.io / AWS Distributed Load Testing:Ezeknél a szolgáltatásoknál csak feltöltöd a k6, JMeter vagy saját konfigurációs scriptjeidet, kiválasztod a régiót és a 50 000 felhasználós terhelést, ők pedig a háttérben azonnal felhúzzák a szükséges infrastruktúrát, majd a teszt végén leállítják azt.

    Összegzés – Melyiket válaszd?

    • Ha kódból írnál teszteket és a legjobb erőforrás-kihasználást akarod minimalizált szerverköltséggel: k6 vagy Gatling.
    • Ha a csapat Pythonban erős: Locust.
    • Ha nulla infrastruktúra-üzemeltetést szeretnél: Grafana Cloud k6 vagy BlazeMeter.
  • JMeter, változó terhelésű tesztelés

    JMeter, változó terhelésű tesztelés

    Mint már korábban talán írtam, nem vagyok egy JMeter guru. Így aztán ha felmerül valami kérdés, az AI-hoz fordulok, mintsem órákat töltsek azzal, hogy a Google segítségével talált linkeket végigolvassam.  Így történt ez most is, amikor egy váltakozó terhelésű tesztet szerettem volna előállítani. Az elmélet megvolt, hiszen csináltam már ilyen HP LoadRunnerrel réges régen, viszont a JMeter beállításaival és technikai adottságaival nem vagyok komfortos, mivel ez egy elég jól konfigurálható „műszer”.

    Nézzük, mint mondott a Gemini:

    Egyszerű eset

    JMeterben a változó terhelésű (ramping, lépcsőzetes vagy hullámzó) tesztelés megvalósítására három fő módszer létezik, a legegyszerűbb beépített megoldástól a legrugalmasabb pluginokig.

    1. Beépített megoldás: Standard Thread Group

    Ha nincs lehetőséged pluginokat telepíteni, a sima Thread Group beállításaival is elérhetsz alapvető terhelésnövekedést (Ramp-up).

    • Ramp-up Period (seconds): Megadja, hogy a virtuális felhasználók mennyi idő alatt induljanak el fokozatosan.
    • Példa beállítás:
      • Number of Threads (users):100
      • Ramp-up Period (seconds):50
      • Loop Count:Infinite (vagy adj meg egy fix időtartamot a Specify Thread lifetime opcióval)
    • Működés: 50 másodperc alatt másodpercenként 2 új virtuális felhasználó lép be, amíg el nem éri a 100-at.

    2. A legrugalmasabb módszer: Ultimate Thread Group (Ajánlott)

    A változó terhelés (pl. hullámzás, lépcsőzetes emelés, hirtelen tüskék/spike tesztek) grafikusan és precízen a JMeter Plugins Manager segítségével telepíthető Custom Thread Groups csomaggal valósítható meg.

    A telepítés után válaszd a jp@gc - Ultimate Thread Group elemet. Ebben egy táblázatban (Threads Schedule) tetszőleges számú terhelési szakaszt kombinálhatsz:

    Start Thread CountInitial Delay (sec)Startup Time (sec)Hold Load For (sec)Shutdown Time (sec)
    1000306010
    200903012020
    • Működés:
      1. Az első sor lefut: 30 mp alatt felmegy 100 felhasználóra, tartja 60 mp-ig, majd leáll.
      2. A második sor 90 mp várakozás után belép, és további 200 felhasználóval megemeli a terhelést (lépcsőzetes teszt).

    3. Kérés/másodperc (RPS/TPS) alapú szabályozás

    Ha nem a virtuális felhasználók száma, hanem a másodpercenkénti kérésszám (Throughput) változtatása a célod:

    1. Throughput Shaping Timer (Plugin):
      • Helyezd a kérések alá (vagy a Thread Group szintjére).
      • Egy táblázatban megadhatod a kívánt RPS-t időtartam alapján:
        • Start RPS:10$\rightarrow$End RPS:50 (Duration:60s) — lineáris emelkedés
        • Start RPS:50$\rightarrow$End RPS:50 (Duration:180s) — állandó terhelés tartása
    2. Concurrency Thread Group + Throughput Shaping Timer:
      • A két plugin összekapcsolható (a Concurrency Thread Group automatikusan beállítja a szükséges virtuális felhasználók számát a Throughput Shaping Timer által kért RPS eléréséhez).

    Gyors összefoglaló a megközelítés kiválasztásához

    • Lépcsőzetes / Hullámzó terhelés userekkel: Use jp@gc - Ultimate Thread Group
    • Fix Target RPS / Áteresztőképesség tesztelése: Use Throughput Shaping Timer
    • Egyszerű lineáris felfutás: Standard Thread Group (Ramp-Up Period)

    Több Thread Group esetén

    Ha több Thread Group-ot használsz egyetlen Test Planen belül, akkor összetett, valósághű terhelési profilokat építhetsz fel. Például szimulálhatsz különböző felhasználói viselkedéseket (pl. 70% vásárló, 30% böngésző) vagy egymásra csúsztatott terhelési hullámokat.

    A több Thread Group összehangolására két alapvető megközelítés létezik: Párhuzamos (egyszerre futnak) és Egymás utáni (szekvenciális).

    1. Párhuzamos futtatás (Alapértelmezett beállítás)

    Alapértelmezetten a JMeter az összes Thread Group-ot egyszerre, párhuzamosan kezdi el futtatni. A változó terhelést az határozza meg, hogy a csoportok időben hogyan vannak beidőzítve egymáshoz képest.

    Példa scenárió: Vásárlási csúcsforgalom szimulációja

    • Thread Group A (Állandó háttérterhelés – Cikkolvasók): Folyamatosan jelen lévő felhasználók.
    • Thread Group B (Lépcsőzetes terhelés – Vásárlók): Hullámokban érkező vásárlók.

    Beállítás Ultimate Thread Group pluginnal:

    Test Plan

    • ⚙️ Test Plan(a „Run Thread Groups consecutively” opció kivétele)
      • 👥 jp@gc - Ultimate Thread Group(Háttérterhelés – Böngészők)
      • 👥 jp@gc - Ultimate Thread Group(Csúcsforgalom – Vásárlók)

    A) Háttérterhelés csoport (Böngészők):

    Start Thread CountInitial Delay (sec)Startup Time (sec)Hold Load For (sec)Shutdown Time (sec)
    5001030010

    (Gyorsan feláll 50 felhasználóra, és végig fut 5 percig.)

    B) Csúcsforgalom csoport (Vásárlók):

    Start Thread CountInitial Delay (sec)Startup Time (sec)Hold Load For (sec)Shutdown Time (sec)
    10060306010
    200180306010

    (A teszt 1. percében belép 100 vásárló, majd a 3. percben egy újabb 200 fős tüske érkezik.)

    2. Szekvenciális (Egymás utáni) futtatás

    Ha a terhelési fázisokat szigorúan egymás után akarod futtatni (pl. Felfűtés $\rightarrow$ Terhelési teszt $\rightarrow$ Kiürülés), be kell kapcsolnod a JMeterben az egymás utáni futtatást.

    Beállítás lépései:

    1. Kattints a Test Plan gyökérelemre.
    2. Pipáld be a Run Thread Groups consecutively (i.e. run one at a time) opciót.

    Példa felépítés:

    Test Plan(Egymás utáni futtatás bekapcsolva)

    • 1️⃣ Thread Group - 1. Fázis (Bemelegítés)
      • Threads: 20, Ramp-Up: 20s, Duration: 60s
    • 2️⃣ Thread Group - 2. Fázis (Fő terhelés)
      • Threads: 200, Ramp-Up: 30s, Duration: 300s
    • 3️⃣ Thread Group - 3. Fázis (Lecsengés)
      • Threads: 10, Ramp-Up: 1s, Duration: 30s
    • Működés: A JMeter megvárja, amíg az 1. csoport teljesen leáll, és csak utána indítja el a 2. csoportot, majd végül a 3.-at.

    💡 Fontos tipp adatok megosztásához a Thread Groupok között

    Ha több Thread Groupot használsz, a sima JMeter változók (${var}) nem terjednek át az egyik csoportból a másikba, mert a változók szál-specifikusak.

    Ha az egyik csoportban (pl. Bejelentkezés) generált adatot akarod használni egy másik csoportban:

    • Használj JMeter Property-ket a megosztáshoz (pl. Groovy scriptben: props.put("token", "${extracted_token}") és a másik csoportban: ${__P(token)}).
    • Használj jp@gc - Inter-Thread Communication plugint az adatok átadására a csoportok között.
  • Apache JMeter és a Throughput Controller

    Mivel napo óta ezzel szórakoztatom magam, gondoltam íratok erről pár sort az AI-val, mint emlékeztető, ha újra elő kell vennem a témát. Röviden: vannak esetek, amikor százalékos arányban kell hívásokat eszközölni a performancia mérésben. Ebben tud segíteni a Throughput Controller.

    Nézzük, mint mond erről az AI:

    A Throughput Controller az Apache JMeter egyik legfontosabb eleme, amikor a valós felhasználói viselkedést szeretnénk szimulálni. Neve ellenére nem a másodpercenkénti kérések számát (RPS) korlátozza (arra a Constant Throughput Timer való), hanem azt határozza meg, hogy a teszt lépései milyen arányban vagy rögzített alkalommal fussanak le.

    Mire jó a Throughput Controller?

    Egy webáruháznál a látogatók nem egyforma arányban böngésznek és vásárolnak:

    • 80% csak böngészi a termékeket.
    • 15% kosárba tesz valamit.
    • 5% eljut a fizetésig.

    A Throughput Controller segítségével pontosan ezt a megoszlást képezhetjük le egyetlen Thread Group-on belül.

    A két fő működési mód (Based On)

    MódLeírásMikor használd?
    Percent ExecutionsA beállított százalékos arányban engedi lefutni a gyermek kéréseket a teszt során.Valós felhasználói eloszlás szimulálásához (pl. 80-15-5% szabály).
    Total ExecutionsLegfeljebb egy megadott fix alkalommal engedi lefutni a kérést, utána kihagyja.Egyszeri beállításokhoz vagy korlátozott műveletekhez (pl. adatbázis-feltöltés).

    Fontos beállítás (Per User): Ha be van pipálva, a számítás nem a teljes tesztre, hanem szálanként (felhasználónként) érvényesül.

    Gyakorlati példa: Webáruház forgalomszimuláció

    Tételezzük fel, hogy 100 szálat (felhasználót) indítunk egy hurokban (Loop Count: 100). A célunk a fent említett 80%-15%-5%-os megoszlás.

    Struktúra a JMeterben:

    Plaintext

    Test Plan
     └── Thread Group (100 Threads, Loop: 10)
          ├── Throughput Controller (Percent Executions: 80.0)
          │    └── HTTP Request: Termékoldal megtekintése
          ├── Throughput Controller (Percent Executions: 15.0)
          │    └── HTTP Request: Kosárba helyezés
          └── Throughput Controller (Percent Executions: 5.0)
               └── HTTP Request: Fizetés
    

    Működés:

    • A 1000 összes lefutásból nagyjából 800 alkalommal a termékoldal kérés fog lefutni.
    • 150 alkalommal a kosárba helyezés.
    • 50 alkalommal pedig a fizetés lép fel.

    Gyakori hibák és tippek

    1. Ne keverd a Constant Throughput Timer-rel: Ha az a célod, hogy a szervert pontosan 100 req/sec terhelés alatt tartsd, használj Timert. A Throughput Controller az arányokról szól, nem a sebességről.
    2. Keresztülfutás (Overhead): Ha a szabályok összege nem 100%, vagy egy szál egyik controllernek sem felel meg az adott iterációban, a szál kihagyja az adott részt és lép a következő hurokra.
    3. Egymásba ágyazás: Összetettebb scenárióknál Simple Controller-rel vagy Transaction Controller-rel kombinálva egész folyamatokat is elhelyezhetsz egy-egy Throughput Controller alá.