Webshop terheléses teszt k6-tal: így írj valós forgatókönyvet éles indulás előtt

A terheléses teszt akkor ér valamit, ha nemcsak azt mutatja meg, hogy a kezdőlap válaszol-e, hanem azt is, hogy a webshop végigviszi-e a vásárlót a termékoldaltól a pénztárig, amikor egyszerre sokan érkeznek.

A kampány előtti kérdés ezért nem az, hogy hány URL-t tudsz meghívni percenként. A valódi kérdés az, hogy a böngészés, a kosár, a készletkezelés és a checkout együtt hogyan viselkedik, miközben a forgalom fokozatosan nő.

Ebben az útmutatóban egy használható k6-forgatókönyvet építünk fel: meghatározzuk a vásárlói útvonalat, különválasztjuk a ramp-up futásokat, kijelöljük a p95- és hibaarány-méréseket, majd az eredményeket szerverkapacitási döntéssé fordítjuk le.

Webshop terheléses teszt k6-tal: a Sybell Hosting szuperhőse a vásárlói útvonalra mutat a böngészéstől a pénztárig, mellette p95 válaszidő-grafikon és szerverek.

Hogyan épül fel a valós webshop-terheléses teszt k6-tal?

A valós webshop-forgatókönyv egymásra épülő vásárlói lépések sorozata, nem egyetlen URL ismételt meghívása. A k6-tal ezért a böngészés, a kosárba helyezés és a pénztár külön szakaszait érdemes modellezni, majd egy közös flow-ban összekapcsolni.

A k6 egy JavaScript-alapú, fejlesztőknek készült terhelés- és teljesítménytesztelő eszköz, amellyel virtuális felhasználókat, HTTP-kéréseket és üzleti folyamatokat szimulálhatsz. A k6 mérőszámokat, küszöbértékeket és fokozatos terhelési profilokat kezel, ezért automatizált tesztfolyamatba is beilleszthető.

A kezdőlap vagy egy cache-elt kategóriaoldal önmagában túl optimista képet adhat. A webshop teljesítményét gyakran a keresés, a szűrés, a kosárfrissítés vagy a fizetési folyamat terheli meg, ezért ezeket nem szabad kihagyni.

Böngészési forgatókönyv

A böngészési szakasz útvonala például: kampány landing page vagy nyitóoldal → kategóriaoldal → szűrés vagy keresés → termékoldal → további termékmegnyitás. A teszt ne mindig ugyanazt a terméket kérje le: használj több kategóriát és véletlenszerűen választott termékazonosítókat, hogy a cache és az adatbázis ne egyetlen URL-re optimalizálja a képet.

A sleep() hívásokkal adj rövid gondolkodási időt a virtuális felhasználóknak. Egy 100 milliszekundumos, folyamatos kérésáradat inkább API-roham, mint vásárlói forgalom; a néhány másodperces szünetekkel felépített útvonal közelebb áll egy valódi kampányhoz.

Kosárba tevési forgatókönyv

A kosárszakaszban a felhasználó valóban helyezzen terméket a kosárba, majd ellenőrizd, hogy a kosár válasza üzletileg is helyes-e. A 200-as HTTP-kód önmagában kevés: a terméknek, a mennyiségnek, az árnak és az esetleges kuponnak is meg kell jelennie a várt állapotban.

Egy kuponos termékbevezetésre készülő, 300 SKU-s WooCommerce-webshopnál például más terhelést jelent 12 különböző termék véletlenszerű kosárba helyezése, mint ugyanazt az egy akciós SKU-t ismételni minden iterációban. A tesztadatokat úgy válaszd meg, hogy a készlet- és kuponlogika is életszerű legyen, de a futás után tisztítható maradjon.

Pénztárforgatókönyv

A checkout a webshop legérzékenyebb pontja, ezért önálló mérési egységként kezeld. A flow tartalmazza a szállítási adatokat, a szállítási módot, a fizetési módot, a rendelés-összesítést és a fizetési szolgáltató sandbox-válaszát.

A session- és tokenkezelést ugyanúgy ellenőrizd, mint a válaszidőt. A siker feltétele például az, hogy a tesztvásárló rendelése létrejön, a rendelési állapot a várt értéket kapja, és a készletmozgás nem hagy maga után olyan adatot, amely a következő futást torzítja. Valódi fizetést ne indíts; a sandbox a checkout-logika terhelés alatti vizsgálatára való.

A kód szerkezetét érdemes üzleti lépések szerint csoportosítani és tagelni. A group() a riportban egységbe rendezi az egyes lépéseket, a kérésekhez adott flow tag pedig lehetővé teszi, hogy flow-nként küszöbértéket állíts be:

import http from 'k6/http';
import { group, sleep } from 'k6';

const BASE_URL = 'https://pelda-webshop.hu';

export default function () {
  group('browse', () => {
    http.get(`${BASE_URL}/termek-kategoria/cipok/`, {
      tags: { flow: 'browse' },
    });
    sleep(3);
  });

  group('cart', () => {
    http.post(`${BASE_URL}/?wc-ajax=add_to_cart`, cartPayload, {
      tags: { flow: 'cart' },
    });
    sleep(2);
  });

  group('checkout', () => {
    http.post(`${BASE_URL}/?wc-ajax=checkout`, checkoutPayload, {
      tags: { flow: 'checkout' },
    });
  });
}

A példában szereplő URL-ek, a cartPayload és a checkoutPayload helyére a saját végpontjaid, tokenjeid és tesztadataid kerülnek. Egy valódi flow-ban lépésenként több kérés is fut, ezért mindegyikhez add hozzá ugyanazt a flow taget. A group() önmagában nem hoz létre flow taget: a csoport neve a group tagbe kerül ::checkout formában, így ha csoportra írnál küszöbértéket, a {group:::checkout} szűrőt kell használnod. Így a k6 riportjában külön látod, melyik flow kezdett lassulni.

A tesztadatokhoz készíts külön mátrixot: melyik termék, kategória, kupon, szállítási mód és fizetési sandbox-válasz szerepel az adott futásban. Rögzítsd a WordPress- és WooCommerce-verziót, a bővítmények állapotát, a cache-beállításokat és a szerver aktuális konfigurációját is. Ha a peak futás után módosítasz valamit, az ismételt mérés csak akkor összehasonlítható, ha ezeket a változásokat feljegyzed.

Milyen ramp-up profillal emeld a terhelést?

A jó ramp-up profil fokozatosan építi fel a forgalmat, és külön választja a működés ellenőrzését, a normál terhelés mérését, a várt csúcsot és a töréspont keresését. Egyetlen, hirtelen indított csúcstesztből nehéz megmondani, mikor és miért romlott a webshop teljesítménye.

A négy egymásra épülő futás legyen a következő:

  • Smoke test: 1–2 virtuális felhasználóval ellenőrizd a teljes útvonalat. A session, a kosár, a checkout-token és a sandbox-fizetés hibamentesen fusson végig.
  • Baseline futás: modellezd a megszokott napi terhelést 10–15 percig. Ez lesz az összehasonlítási alap a kampány előtti és utáni futásokhoz.
  • Peak futás: fokozatosan érd el a kampány vagy az éles indulás becsült maximumát, majd tartsd ezen a szinten elég ideig ahhoz, hogy a cache, a PHP workerek és az adatbázis terhelése beálljon.
  • Stress futás: kontrolláltan lépj a várt csúcs fölé. A cél a lassulás és a töréspont mintázatának megfigyelése, nem a rendszer felügyelet nélküli túlterhelése.

A k6-ban két eltérő logika közül választhatsz:

Executor Mit szabályoz? Mikor válaszd?
ramping-vus Az egyidejűleg aktív virtuális felhasználók számát Ha azt akarod látni, hogyan viselkedik a webshop adott számú párhuzamos vásárlónál
ramping-arrival-rate Az időegység alatt induló iterációk számát Ha a kérdésed a beérkező forgalom ütemére vonatkozik, például kampány vagy launch előtt

A ramping-vus zárt modell: minden virtuális felhasználó végigfuttatja a saját iterációját, és csak utána kezd újat. Ha a webshop lassul, a VU-k tovább várnak egy-egy válaszra, így percenként kevesebb iteráció indul, és a terhelés magától csökken. Ez jól mutatja a párhuzamos felhasználók hatását, de egy kampányroham valódi ütemét alábecsülheti, mert a valódi vásárlók nem várják meg, amíg a többiek végeznek.

A ramping-arrival-rate nyílt modellként az iterációk indítási ütemét szabályozza, nem azt feltételezi, hogy minden felhasználó ugyanabban a ciklusban mozog. Itt a preAllocatedVUs kulcsfontosságú: ha kevés VU áll rendelkezésre, a terhelésgenerátor nem tudja tartani a kívánt érkezési ütemet. A 150 iteráció percenként ezért nem azonos 150 egyidejű látogatóval, mert egy iteráció több HTTP-kérést és eltérő hosszúságú checkoutot tartalmazhat.

Kezdésnek használhatsz egy 45 perces keretet: 5 perc bemelegítés, 10 perc fokozatos emelés, 15 perc a várt csúcson, 10 perc kontrollált túlterhelés, majd 5 perc levezetés. A célértékeket a saját forgalmi adataidból és a baseline futásból vedd, ne általános internetes példákból. A futások között ne ürítsd ki automatikusan az összes mérési előzményt: a baseline, a peak és a stress eredménye kerüljön ugyanabba a riportba, ugyanazokkal a flow-tagekkel. Így látszik, hogy a lassulás fokozatos volt-e, vagy csak egy hibás tesztadat okozta.

Mit mérj a terheléses tesztben: p95, hibaarány és erőforrások?

Egy terheléses teszt akkor használható, ha nemcsak az átlagos válaszidőt nézed, hanem a lassabb kéréseket, a hibás kéréseket és a szerveroldali erőforrásokat is ugyanahhoz a futáshoz kötöd. A válaszidő megmutatja, mit érez a vásárló, a monitoring pedig segít megérteni, miért alakult úgy az eredmény.

A p95 válaszidő azt mutatja meg, hogy a kérések 95 százaléka milyen időn belül fejeződik be. A p95 azért hasznosabb az átlagnál, mert nem rejti el a lassabb, még mindig tömegesen előforduló kéréseket, amelyek egy kampány alatt már érezhetően rontják a vásárlói élményt.

A minimum mérési készlet

A k6 riportjában legalább ezeket kövesd:

  • http_req_duration: átlag mellett p95 és p99, lehetőleg flow-nként bontva;
  • http_req_failed: a hibás HTTP-kérések aránya;
  • checks: üzleti ellenőrzések, például bekerült-e a termék a kosárba vagy létrejött-e a rendelés;
  • iterations és http_reqs: a végrehajtott folyamatok és kérések mennyisége;
  • dropped_iterations: az el nem indított iterációk száma, amely arrival-rate futásnál VU- vagy rendszerlimitre is utalhat.

A küszöbértékeket a baseline-hoz és az üzleti elváráshoz igazítsd. Az alábbi csak minta: az 1 százalék alatti hibaarány és a checkout 1200 ms alatti p95-je nem univerzális igazság, hanem egy olyan ellenőrzés, amelyet a saját üzleti folyamatodhoz kell kalibrálni.

export const options = {
  thresholds: {
    http_req_failed: ['rate<0.01'],
    'http_req_duration{flow:checkout}': ['p(95)<1200'],
  },
};

A flow:browse, flow:cart és flow:checkout tagek lehetővé teszik, hogy ne egyetlen összesített számból próbáld kitalálni, mi romlott el. Ha az átlag jó, de a checkout p95-je meredeken nő, a kampány szempontjából a lassú pénztár a fontos jel. A p99-et se hagyd figyelmen kívül: néhány nagyon lassú kérés nem mindig változtatja meg látványosan a p95-öt, mégis hibás külső API-hívásra vagy időszakos adatbázis-zárra hívhatja fel a figyelmet.

Szerveroldali mérőszámok

A k6 mellé gyűjts CPU- és memóriahasználatot, lemez-I/O-t, IOPS-ot, adatbázis-kapcsolatszámot, PHP worker-terhelést, cache hit/miss arányt és hálózati forgalmat. A tárhely erőforrás-felhasználásának vizsgálatáról szóló útmutató segít abban, hogy a k6 görbéit ne önmagukban olvasd.

Képzeld el úgy, hogy a k6 megmutatja, mit érez a vásárló az ajtón keresztül: mennyit vár a kasszánál. A szervermonitoring azt mutatja meg, mi történik odabent a raktárban és a kasszánál: elfogy-e a PHP worker, sorban állnak-e az adatbázis-kapcsolatok, vagy a háttértár dolgozik a határán.

Hogyan fordítsd le a mérési eredményt szerverkapacitásra?

A mérésből akkor lesz kapacitásdöntés, ha a p95 válaszidőt, a hibaarányt, a dropped_iterations értékét és az erőforrásgörbéket együtt olvasod. Egyetlen lassú futás még nem bizonyít infrastruktúralimitet; az ismételhető mintázat és a terhelési szinthez kötött változás már igen erős jel.

Négy tipikus mintázat

  • Magas p95 és magas CPU- vagy PHP worker-terhelés: alkalmazásoldali, PHP- vagy webszerveres szűk keresztmetszetre utal. Előbb a lassú végpontokat és a párhuzamos feldolgozást vizsgáld.
  • Magas p95 és magas adatbázis- vagy I/O-terhelés: lekérdezési, indexelési vagy háttértár-probléma valószínű. A checkout és a keresés különösen gyakran hozza elő ezt a mintát.
  • Növekvő hibaarány alacsony szerverterhelés mellett: külső API, fizetési sandbox, sessionkezelés vagy alkalmazáslogika lehet a hibaforrás. Ilyenkor a nagyobb szerver önmagában nem biztos, hogy megoldja a problémát.
  • Növekvő dropped_iterations érték: először ellenőrizd a preAllocatedVUs értékét és a terhelésgenerátor erőforrásait. Ha a válaszidő romlásával együtt nő, a rendszer lassulása is hozzájárulhat; ha már a futás elején megjelenik, a k6-környezet lehet alulméretezett.

A döntéshez hasonlítsd össze a baseline-, peak- és stress-futás azonos flow-jait. Jegyezd fel azt a terhelési szintet, ahol a p95 tartósan romlik, majd futtasd újra a tesztet a javítás után. Így nem érzésre választasz szerverkörnyezetet, hanem megmutatható, hogy a változtatás melyik mérőszámot javította. A riportban külön jelöld a terhelésgenerátor, a webshop és a külső szolgáltatások állapotát. Ez a bontás megakadályozza, hogy egy hálózati vagy fizetési sandbox-problémát tévesen szerverkapacitás-hiányként kezelj.

Mikor indokolt VPS vagy dedikált szerver?

VPS akkor kerül elő, amikor a webshopnak a megosztott környezetnél jobban kontrollálható, elkülönített erőforrásokra van szüksége, és a kapacitást a teszt eredményei alapján szeretnéd tovább méretezni. A Sybell Hosting Prémium AMD virtuális szerverei (EPIC Titan VPS5 és EPIC Titan VPS10) 4. generációs AMD EPYC processzoron, DDR5 5600 MHz-es memórián és NVMe U.3 SSD-s RAID10 tárolón futnak. A gyors memória és háttértár pont ott ad tartalékot, ahol a terheléses teszt a legtöbbször szűk keresztmetszetet mutat: a checkout és a keresés adatbázis- és I/O-terhelésénél.

Dedikált szerver akkor indokolt, ha tartósan nagy a terhelés, speciális konfigurációra van szükséged, vagy teljes fizikai gépet állítanál a webshop mögé. A Sybell Hosting dedikált szerverei IPMI IP KVM konzollal távolról is teljes hozzáférést adnak a géphez. A redundáns tápegység és a hot-swap meghajtóhelyek az üzembiztonságot szolgálják, az opcionális hardveres RAID és a 10 Gbit/s-os hálózati kártya pedig nagy forgalomnál is tartalékot ad.

Ha a mérés a szerverváltás irányába mutat, de nem szeretnéd saját csapatodra venni az üzemeltetési terheket, a Sybell Hosting menedzselt szervere lehet a következő vizsgálandó irány. A kapacitásváltás előtt azonban mindig különítsd el az alkalmazás-, adatbázis- és infrastruktúrahibát; így nem drágább környezetben próbálsz megoldani egy hibás checkout-flow-t.

Gyakori kérdések

Kell valódi fizetést futtatni a checkout terheléses tesztjéhez?

Nem, a checkout terheléses teszt sandbox fizetési környezettel is felépíthető. A cél a sessionkezelés, a pénztárlogika és a rendelésfolyamat terhelés alatti vizsgálata, nem valódi tranzakciók indítása.

Honnan futtassam a k6-ot, hogy a terhelésgenerátor ne torzítsa a mérést?

A k6-ot külön gépről vagy felhőkörnyezetből futtasd, amely nem ugyanazokat a CPU-, memória- és hálózati erőforrásokat használja, mint a webshop. A terhelésgenerátoron is figyeld a CPU-t, a memóriát és a hálózatot, mert egy saját oldali limit félrevezető eredményt ad.

Futtathatok-e terheléses tesztet éles webshopon?

Igen, de csak kontrollált idősávban, sandbox fizetéssel, tisztítható tesztadatokkal és az üzemeltető előzetes egyeztetésével. Éles rendszeren a terheléses teszt célja a felügyelt mérés, nem a meglepetésszerű forgalomgenerálás.

Hány virtuális felhasználóval induljak?

Először 1–2 virtuális felhasználóval ellenőrizd, hogy a teljes flow stabilan lefut-e. Ezután a baseline futásból és a kampány várható forgalmából számold ki a fokozatos emelés célértékeit.

Mikor érdemes ramping-arrival-rate alapú k6-szcenáriót használni?

Akkor érdemes ezt az executort választani, amikor az üzleti kérdésed a beérkező forgalom üteméhez kötődik, például kampány- vagy launch-helyzetben. A ramping-arrival-rate az időegység alatt indított iterációk számát szabályozza, ezért a preAllocatedVUs értékét is a várható iterációs időhöz kell igazítanod.

Összegzés

A jó terheléses teszt valós vásárlói útvonalat modellez, fokozatosan építi fel a csúcsot, p95-ben és hibaarányban mér, majd az eredményt szerverkapacitási döntéssé alakítja. Ha a baseline és a stress-futás már egyértelműen nagyobb környezetet indokol, ne találgass: a mérési mintázat alapján válassz következő infrastruktúraszintet.

Ha a mérés azt mutatja, hogy a webshopod kinőtte a jelenlegi környezetét, nézd meg a Sybell Hosting Prémium AMD virtuális szervereit és dedikált szervereit.

Prémium virtuális szerver csomagjaink »