Konrad Kowalski (rootsher)Principal Platform & Reliability Architect000111111101011011011111111000011010001010110000

Performance tests i load tests: zachowanie pod ruchem

data
kategoria
Testing
także w
Capacity & Performance · Observability
czytanie
2 min / 397 słów

System może zwracać poprawną odpowiedź i nadal być zepsuty.

Jeżeli checkout działa przy jednym użytkowniku, ale przy normalnym ruchu odpowiada po pięciu sekundach, test poprawności niczego nie uratował.

To jest miejsce dla performance tests, load tests i stress tests.

Co to za rodzaj testu

Performance test mierzy zachowanie systemu w czasie.

Może sprawdzać:

text
latency
throughput
czas startu
zużycie CPU
zużycie pamięci
liczbę zapytań do bazy
czas renderowania

Load test sprawdza system pod spodziewanym obciążeniem.

Stress test celowo wychodzi poza spodziewane obciążenie, żeby znaleźć granicę.

Te nazwy są blisko siebie, ale nie znaczą tego samego.

Performance test

Performance test może być mały.

Nie musi zawsze oznaczać wielkiego testu ruchu.

Przykłady:

text
funkcja przetwarza 10 000 rekordów poniżej 200 ms
endpoint nie robi więcej niż 3 zapytania do bazy
render tabeli mieści się w budżecie czasu
worker przetwarza batch bez wzrostu pamięci

Taki test łapie regresję kosztu.

Kod nadal daje poprawny wynik, ale robi to wolniej albo drożej.

Load test

Load test pyta:

text
czy system wytrzymuje ruch, którego się spodziewamy?

To wymaga scenariusza.

Nie wystarczy liczba requestów na sekundę.

Trzeba wiedzieć:

text
jakie endpointy
jaki rozkład ruchu
ilu użytkowników
ile zapisów
ile odczytów
jakie dane
jaki czas trwania

Load test bez realistycznego profilu ruchu jest łatwy do uruchomienia i trudny do interpretacji.

Stress test

Stress test pyta:

text
gdzie system pęka?

To nie jest test do codziennej bramki przy każdym pull requeście.

To narzędzie do poznania granic.

Dobry stress test mówi nie tylko, przy jakim obciążeniu system przestaje spełniać wymagania.

Mówi też, jak przestaje działać.

text
czy rośnie latency
czy pojawiają się 500
czy baza dobija do CPU
czy kolejka narasta
czy autoscaling nadąża
czy system degraduje się łagodnie

Co się dzieje, kiedy ich nie ma

Bez testów wydajnościowych performance zostaje opinią.

Ktoś mówi "powinno wystarczyć".

Ktoś patrzy na średni czas odpowiedzi.

Ktoś inny sprawdza tylko lokalnie.

Problem wychodzi dopiero wtedy, kiedy ruch jest prawdziwy.

Wtedy testem staje się produkcja.

Jeżeli nie ma obserwowalności, nawet wynik tego testu jest nieczytelny.

Budżety zamiast ogólnych oczekiwań

Performance test powinien mieć budżet.

text
p95 poniżej 300 ms
mniej niż 5 zapytań SQL
start poniżej 2 s
batch poniżej 1 GB RAM
checkout obsługuje 200 RPS przez 15 minut

Bez budżetu test tylko mierzy.

Z budżetem może zatrzymać regresję.

Budżet nie musi być idealny od początku.

Lepiej mieć prostą granicę i ją korygować niż mieć same wykresy bez decyzji.

Narzędzie ze stacka

Do load tests wybrałbym k6.

Jest wystarczająco prosty, żeby opisać scenariusz w kodzie, i wystarczająco blisko DevOps, żeby uruchamiać go z pipeline albo ręcznie przed większą zmianą.

Dla backendu Node testowałbym nim publiczne endpointy i krytyczne przepływy API.

Dla frontu nie zastępuje to testów renderowania, ale może sprawdzić backendowy koszt ścieżek używanych przez React.

Przykładowy sensowny cel:

text
checkout API utrzymuje p95 poniżej 300 ms przy spodziewanym RPS

Bez budżetu k6 jest tylko generatorem ruchu.

Z budżetem staje się bramką jakości.

Kiedy test jest mylący

Test wydajnościowy jest mylący, kiedy środowisko nie przypomina problemu.

text
inna baza
inne indeksy
inne limity CPU
brak TLS
brak cache miss
za mały dataset
brak konkurencji zapisów

Nie każdy test musi być produkcją.

Ale trzeba wiedzieć, czego test nie symuluje.

W przeciwnym razie wynik wygląda naukowo, ale opisuje inny system.

Ostatnia część serii dotyczy warstwy, którą często nazywa się konfiguracją, chociaż potrafi zepsuć aplikację równie skutecznie jak kod.