Badania obciążenia i profile naprężeń
Krótkie podsumowanie
Testowanie obciążenia jest testem wydajności i odporności systemu w realistycznych i ekstremalnych scenariuszach. Podstawą sukcesu jest prawidłowy model ruchu (otwarty vs zamknięty), stałe SLO, czysta metryka (opóźnienie/przepustowość/błędy/nasycenie), reprezentatywne dane, automatyzacja i powtarzalność. Rezultatem nie jest „RPS”, ale rozwiązanie: gdzie są wąskie gardła, ile kosztuje wydajność, gdzie jest próg awarii i jak ją przenieść.
SLO/SLI i mierniki docelowe
SLO (przykład): p95 API ≤ 250 ms, p99 ≤ 600 ms; błąd ≤ 0. 3 %/30 dni.
SLI: latencja (p50/p95/p99), przepustowość (RPS/CPS/QPS), saturate (CPU/heap/GC/FD/conn), обибка (5xx, timeouts), оверена (głębokość/lag), DB (blokady, powolne zapytania), KK (współczynnik trafienia).
Błąd i wyzwalacze nasycenia (na przykład procesor> 75% lub głębokość kolejki> X → degradacja).
Rodzaje badań
1. Punkt odniesienia/punkt odniesienia - pojedyncza usługa/punkt końcowy, warunki „idealne”.
2. Obciążenie - realistyczny „dzień roboczy” + ramp-up/ramp-down.
3. Naprężenie - zwiększyć obciążenie do degradacji i utrwalenia punktu breakpoint.
4. Spike - ostry skok (x2-x10 w sekundach/minutach).
5. Mocz/wytrzymałość - długotrwała (8-72 h): wycieki pamięci, dryf opóźnienia.
6. Pojemność - obciążenie krokowe dla krzywej wydajności i planowania pojemności.
7. Degradacja/Chaos-mix - obciążenie + częściowe awarie (powolna baza danych, kropla pamięci podręcznej, „zawalone” oklaski).
Modele ruchu: Otwarte vs zamknięte
Model otwarty (bardziej realistyczny dla Internetu): użytkownicy pochodzą z natężenia (strumień Poissona). Jeśli system zwalnia, żądania są gromadzone, a nie „zamrożone”.
Model zamknięty - stała liczba użytkowników wirtualnych (VU) z czasem myślenia. Gdy opóźnienie wzrasta, RPS sztucznie spada - ostrożnie z wnioskami.
Zalecenie: w przypadku API typu front-end należy stosować model otwarty (k6-arrival-rate '), w przypadku wewnętrznych skryptów synchronicznych - łączyć z zamkniętymi.
Profile obciążenia (szablony)
„Normalny dzień”: podstawowe tło + dzienne wahania.
„Wydarzenie szczytowe”: 10-30 minut przed startem (rozgrzewka), ostry skok na starcie, płaskowyż, ogon.
„Turniej/strumień”: stopnie drabiny, powtarzane szczyty w odstępach czasu.
„Degradacja infrastruktury”: połowa pamięci podręcznej jest pusta, jeden region jest wyłączony, opóźnienie PSP wzrasta.
„Awaria”: przepływ ruchu do ochrony w ciągu 1-5 minut; sprawdzanie burz automatycznych/HPA/Retry.
Dane środowiskowe i przygotowanie
Dane testowe: realistyczna kardynalność (dostawcy, waluty, kraje), brudne pola, dystrybucje zapytań (Pareto/Zipf).
Sekrety/PII: Anonimizacja; klawisze/PSP - piaskownica.
Środowisko: dedykowane stanowisko perf, izolacja od integracji (mock/stab), stałe wersje.
Obserwowalność: metryka (Prometheus), kłody (Loki/ELK), ślady (OTel). Rekord build-id w odpowiedziach.
Antystorm Retray i Idempotencja
Retrai tylko dla operacji idempotentnych; ustawić ponownie budżet (np. ≤ 10% ruchu).
Wykładniczy backoff + jitter; „zawalenie” identycznych PS.
W przypadku płatności - idempotentne klucze i wyraźne statusy.
Ochrona przed grzmotaniem stada: zamki pamięci podręcznej, SWR, lokalne semafory.
Narzędzia i wzory
k6 (skryptowanie, model otwarty, dobre raportowanie), szarańcza (skrypty Pythona), Gatling (Scala), JMeter (szeroki zakres protokołów).
Protokoły: HTTP/1. 1/2/3, gRPC, WebSocket, TCP/UDP; serwer push nie testuje „jako GET”.
Generowanie ruchu: pozioma skalowanie generatorów, kontrola wąskiego gardła sieci.
Usuwanie profili: pprof/async-profiler/ebpf pod obciążeniem, trasy OTel.
javascript import http from 'k6/http';
import {check, sleep} from 'k6';
export const options = {
scenarios: {
warmup: { executor: 'ramping-arrival-rate', startRate: 50, timeUnit: '1s',
preAllocatedVUs: 200, stages: [ { target: 200, duration: '5m' } ] },
spike: { executor: 'constant-arrival-rate', rate: 1200, timeUnit: '1s',
preAllocatedVUs: 2000, startTime: '6m', duration: '3m' }
},
thresholds: {
http_req_failed: ['rate<0. 3%'],
http_req_duration: ['p(95)<250', 'p(99)<600']
}
};
export default function () {
const res = http. get(`${__ENV. BASE_URL}/api/v1/catalog? c=${Math. floor(Math. random()1000)}`);
check(res, { 'status is 200': (r) => r. status === 200 });
sleep(Math. random()0. 9) ;//think time (for closed parts of the script)
}
Procedura
1. Hipoteza → które wąskie gardła są prawdopodobne (procesor, DB, pamięć podręczna, sieć, TLS, GC).
2. Profil → scenariusze/trasy, udziały w ruchu, modele (otwarte/zamknięte), dane.
3. Nagrzewanie → pamięć podręczna/połączenia/TLS/tłumacze.
4. Zwiększenie → etap do intensywności docelowej.
5. Plateau → zbiór stabilnych metryk i śladów.
6. Stres/spadek → znaleźć punkt przerwy, obserwować automatyczną skalę.
7. Analizuj → korelować metryki, flamegraf, raport, i plan zmian.
8. Repruf → powtórzyć przez rurociąg CI (Region Perf).
Analiza wyników
Ładowanie → krzywa opóźnienia/błędu: szukanie łokcia (pojemność).
Opóźnienie podziału: sieć (DNS/TLS/connect), serwer proxy, aplikacja, baza danych, połączenia zewnętrzne.
Nasycenie: CPU> 75-85%, GC pauza> p95, I/O czeka, kolejka zadań.
Elastyczność: czas reakcji autoskalowej (HPA/KEDA), start na zimno, nagrzewanie pamięci podręcznej.
Koszt: $/1000 RPS przy docelowym SLO, maksymalna prognoza budżetu.
Praktyki inżynierskie
Wskaźniki degradacji: „ogony” p99, wzrost kolejki, spadek współczynnika trafienia, wzrost prób retrasy.
Wyklucz konfoundery: limity deskryptorów plików, sysctl, conn-pool, 'reuseport', łańcuchy TLS, OCSP.
DB: indeksy/plany/pamięć podręczna zapytania, pula połączeń, operacje wsadowe, obciążenie zwrotne producentów.
Bufety: rozmiar/eksmisja, gorące klucze, replikacja.
Sieć/krawędź: HTTP/2/3, wznowienie ≥ 70%, Brotli, klucz pamięci podręcznej CDN, pamięć podręczna wielopoziomowa.
Obserwowalność pod obciążeniem
Mierniki: system (CPU/mem/IO), czas trwania (GC/hałd), sieć (RTT/loss/ECN), L7 (p95/99, 5xx/429), kolejki, klastry bazy danych/pamięci podręcznej.
Ślady: obejmują pobieranie próbek na „ogonach” (na podstawie ogona), znakach build-id/canary.
Kłody: agregacja błędów z ograniczeniem objętości (tak aby nie „DOSor” log-pipeline).
Eksperymenty: w raporcie należy zapisać flagi funkcji i konfiguracje.
Automatyzacja i CI/CD
Perf-jobs w CI (dym 3-5 min, noc 30-60 min, moczenie tygodniowe).
Granice tolerancji: opóźnienie/błędy/zasoby → „break build” w regresji.
Artefakty: wykresy, flamegrafy, profile, raporty JSON (k6/jtl).
Wersioning danych i skryptów, PR-przegląd skryptów perf.
iGaming/specyficzne dla fintechu
Turnieje/mecze: spike + plateau; Rozgrzewanie TLS/DNS/CDN, zwiększone limity puli, szare trasy dla botów.
Płatności/PSP: granice piaskownicy, idempotencja, rygorystyczne terminy; sprawdzanie trybu degradacji (pamięć podręczna, kolejki).
Jackpoty/wydarzenia: atomowość i konsystencja, brak pochłaniania, obciążenie RTP/liderów.
Przeciwdziałanie oszustwom/AML: obciążenie zasad/ML punktacja, backpressure, deduplikacja zdarzeń.
Regulacja: rejestrowanie mierników i wersji w szczytach, sprawozdania do audytu.
Lista kontrolna uruchomienia
- Stałe SLO/SLI i czerwone linie (błąd/opóźnienie/nasycenie).
- Zatwierdzono scenariusze obciążenia i profile (otwarte/zamknięte, kolce/moczenie/naprężenie).
- Data realistic, PII maskowane, integracje piaskownica/mock.
- Obserwowalność gotowa: mierniki/ścieżki/dzienniki, znaczniki uwalniania.
- Konfiguracje systemu (ulimit/sysctl/pools) są udokumentowane.
- Auto-scale/cache plan rozgrzewki i kryteria wsteczne.
- Wpisy progowe i plan dyżuru.
- Przygotowywany jest szablon raportowania (wykresy, wnioski, działania).
Częste błędy
Test zamkniętego modelu daje „zielony” wynik, a produkt spada (nie można ignorować otwartego modelu).
Dane niereprezentacyjne (jedna waluta/jeden dostawca) → fałszywe wnioski.
Zero przygotowania: zimne bufory/TLS/połączenia → nadmierne opóźnienie na początku.
Retrai bez ograniczeń → burza i kaskada pada.
Te same profile dla wszystkich usług → pominięcie prawdziwych „gorących miejsc”.
Brak biegów moczenia → wycieki pamięci i dryfowanie nie są widoczne.
Nieprzezroczyste wyniki: brak śladów/flamegrafów → brak możliwości zlokalizowania wąskiego gardła.
Mini playbooks
Zdefiniowanie punktu breakpoint
1. Kroki 10-20% obciążenia co 5-10 minut. 2) Napraw moment, w którym p95 gwałtownie wzrasta, a błędy> SLO. 3) Usuń profile procesora/DB/pamięci podręcznej. 4) Plan optymalizacji i powtórzyć.
Lądując w burzach retray
1. Ograniczyć retry-budget i włączyć backoff + jitter. 2) Wprowadź zawalenie/SWR. 3) Zezwalaj na „tryb degradacji” (ograniczona funkcjonalność). 4) Podwójna kontrola iempotencji.
Wydarzenie szczytowe (turniej) - wstępny plan
1. Ogrzewanie basenów CDN/DNS/TLS. 2) Zwiększenie celu HPA, przygotowanie rezerwy. 3) Oddzielne limity stawek dla botów. 4) Deski rozdzielcze w trybie szczytowym, most komunikacyjny dyżurny.
Noc moczenia
1. 8-12 godzin stabilnego obciążenia. 2) Monitor hałdy/FD/conn/GC-pausy. 3) Sprawdź deltę p95 i współczynnik trafienia. 4) Naprawić przecieki i dryfować.
Wynik
Testowanie obciążenia jest procesem decyzyjnym inżynierii, a nie "wyścigiem dla RPS. "Modele prawdziwe profile (zwłaszcza otwarty model), przechwytywanie SLO, pobieranie metryk i śladów, poszukiwanie kolana wydajności i liczenie kosztów wydajności. Automatyzuj biegi, zachowuj odwrót przeciwburzowy i planuj wydarzenia szczytowe - w ten sposób platforma będzie przewidywalna i stabilna w najbardziej stresujących momentach.