Wszystko zaczyna się od pytania: co robią ci użytkownicy? Tysiąc osób zalogowanych do aplikacji nie wysyła tysiąca żądań na sekundę, a strona serwowana z pamięci podręcznej kosztuje sto razy mniej niż strona generowana przy każdej wizycie. Ten poradnik przelicza użytkowników na żądania, żądania na procesor i pamięć, a następnie pokazuje, jak to sprawdzić testem obciążeniowym.
„Jednocześni użytkownicy” to trzy różne wielkości, zależnie od tego, kto o nich mówi:
Od jednej wielkości do drugiej przechodzi się dzięki prawu Little’a: liczba żądań w toku równa się przepustowości, w żądaniach na sekundę, pomnożonej przez średni czas trwania żądania.
Przykład. 600 użytkowników aktywnych jednocześnie, z których każdy wysyła żądanie co 20 sekund, daje 30 żądań na sekundę. Jeśli każde żądanie trwa 100 ms, serwer ma średnio tylko 3 żądania w toku. Wyzwanie leży gdzie indziej: w szczytach i w wolnych żądaniach.
Żądanie zajmuje procesor przez czas swoich obliczeń: wykonanie kodu, zapytanie do bazy, zbudowanie odpowiedzi. Jeden vCPU przetwarza więc najwyżej 1 000 ÷ t żądań na sekundę, gdzie t to czas obliczeń jednego żądania w milisekundach. Czas oczekiwania (na zewnętrzne API, na dysk) nie zajmuje procesora, ale zajmuje workera.
| Rodzaj żądania | Typowy czas obliczeń | Na vCPU, rząd wielkości |
|---|---|---|
| Plik statyczny lub strona serwowana z pamięci podręcznej | Poniżej 1 ms | Kilka tysięcy żądań na sekundę |
| Strona WordPress serwowana z pamięci podręcznej stron | Od 1 do 5 ms | Kilkaset na sekundę |
| API JSON (Node.js, Go, FastAPI) z zapytaniem SQL korzystającym z indeksu | Od 5 do 20 ms | Od 50 do 200 na sekundę |
| Strona WordPress lub Laravel generowana przy każdej wizycie | Od 100 do 300 ms | Od 3 do 10 na sekundę |
| Raport, eksport, generowanie PDF | Od 500 ms do kilku sekund | Mniej niż 2 na sekundę |
Przy tych rzędach wielkości 30 żądań API na sekundę po 10 ms obliczeń zajmuje 30 % jednego vCPU. Te same 30 żądań na sekundę na stronach WordPress bez pamięci podręcznej wymaga od 3 do 9 vCPU. Pamięć podręczna stron służy właśnie do tego, aby przenieść stronę z czwartego wiersza tabeli do drugiego.
Każde żądanie w toku obsługuje worker, a workery zajmują pamięć bez względu na to, czy pracują. To często pamięć, bardziej niż procesor, wyznacza liczbę żądań przetwarzanych równolegle:
pm.max_children wyznacza limit: 20 procesów to od 800 MB do 1,6 GB.max_connections.Połączenia stałe (websockety, powiadomienia w czasie rzeczywistym) liczy się osobno: otwarte bez przerwy, zajmują niewiele procesora i po kilkadziesiąt kilobajtów pamięci każde. Serwer Node.js utrzymuje ich tysiące w kilkuset MB.
W rzeczywistej aplikacji serwer rzadko osiąga limit tam, gdzie się tego spodziewamy. Najczęstsze przyczyny, w kolejności, w jakiej warto ich szukać:
pg_stat_statements w PostgreSQL lub dziennik wolnych zapytań MySQL.Rzędy wielkości dają pierwszy rozmiar; test obciążeniowy daje rzeczywisty. Zasada: symulować coraz większą liczbę użytkowników na kopii aplikacji i odnotować moment, w którym czas odpowiedzi gwałtownie rośnie.
wrk -t2 -c50 -d30s --latency https://test.panstwa-strona.com/
Dla pełnej ścieżki (logowanie, nawigacja, wyszukiwanie) k6 opisuje scenariusz w JavaScripcie i zwiększa obciążenie etapami:
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 100 },
{ duration: '2m', target: 300 },
{ duration: '5m', target: 300 },
{ duration: '2m', target: 0 },
],
thresholds: { http_req_duration: ['p(95)<500'] },
};
export default function () {
http.get('https://test.panstwa-strona.com/');
sleep(15);
}
htop dla procesora, free -h dla pamięci, logi dla błędów.Kolejność, która kosztuje najmniej i daje najwięcej:
Pierwsze trzy kroki obejmują zdecydowaną większość aplikacji biznesowych, stron i API: kilkuset użytkowników aktywnych jednocześnie mieści się na jednym dobrze skonfigurowanym serwerze.
VPS Pro jest dostępny w sześciu rozmiarach, na procesorach Intel Xeon, pamięci ECC i SSD NVMe w konfiguracji lustrzanej, i przechodzi na większy rozmiar w dowolnej chwili, bez ponownej instalacji. Kompleksowe wsparcie jest w cenie: proszę nam napisać, ilu użytkowników spodziewają się Państwo na start i za rok, a doradzimy rozmiar; a gdy jakaś strona zwalnia, diagnozujemy i wskazujemy, co zrobić, od systemu po kod Państwa aplikacji.
W przypadku API lub aplikacji, której żądania wymagają od 10 do 20 ms obliczeń, kilkuset użytkowników aktywnych jednocześnie. W przypadku strony WordPress bez pamięci podręcznej stron około stu. Różnica wynika z czasu obliczeń każdego żądania i z pamięci podręcznej, dlatego warto przeprowadzić test obciążeniowy.
Liczba odwiedzających dziennie niewiele mówi: liczy się szczyt. Aby przejść od jednej wielkości do drugiej, proszę podzielić dzienne wizyty przez godziny aktywności, pomnożyć przez liczbę odsłon na wizytę, a następnie przez współczynnik szczytu od 3 do 5. 10 000 wizyt w ciągu 10 godzin, po 4 strony każda, daje średnio około 1 strony na sekundę, a w szczycie od 3 do 5.
Trzy sygnały: czas odpowiedzi rośnie razem z ruchem, procesor utrzymuje się powyżej 80 % w godzinach szczytu lub dostępna pamięć spada prawie do zera. Logi serwera WWW pokazują wtedy błędy 502 lub 504, a żądania czekają na wolnego workera.
Tak: połączenie websocket pozostaje otwarte bez przerwy. Zużywa niewiele procesora i kilkadziesiąt kilobajtów pamięci. Serwer Node.js utrzymuje ich tysiące; procesor obciążają bardziej wysyłane wiadomości niż otwarte połączenia.
Simafri
Porozmawiajmy o Państwa projekcie
Proszę powiedzieć nam w kilku słowach, czego Państwo potrzebują: odpowiemy szybko.
Dziękujemy! Państwa zapytanie zostało wysłane. Wkrótce się odezwiemy.
Wolą Państwo e-mail? Proszę napisać do nas na support@simafri.com.