Obecnie mam serwer Apache2 działający z OpenVZ VPS mpm-prefork
i mod_php
na nim z 512 MB pamięci rzeczywistej / 1024 M pamięci RAM z możliwością pękania (bez wymiany). Po przeprowadzeniu niektórych testów stwierdziłem, że maksymalny rozmiar procesu, jaki otrzymuje Apache, to MaxClients
23 MB, więc ustawiłem 25 (23 MB x 25 = 575 MB, ok dla mnie). Postanowiłem uruchomić testy obciążenia na moim serwerze, a wyniki mnie zaskoczyły.
Używam ab
na swoim komputerze stacjonarnym, aby poprosić o stronę główną z bloga Wordpress.
Kiedy uruchamiam ab
z 24 jednoczesnymi połączeniami, wszystko wydaje się w porządku. Jasne, procesor idzie w górę, wolna pamięć RAM spada, a wynik wynosi około 2-3s czasu odpowiedzi na żądanie.
Ale jeśli uruchomię ab
z 25 jednoczesnymi połączeniami (mój limit serwerów), Apache po prostu zawiesi się po kilku sekundach. Zaczyna przetwarzać żądania, potem przestaje odpowiadać, procesor wraca do 100% bezczynności i kończy się limit ab
czasu. Dziennik Apache mówi, że osiągnął MaxClients
.
Gdy tak się dzieje, Apache blokuje się przy 25 uruchomionych procesach (wszystkie są w „W”, jeśli sprawdzę status serwera) i dopiero po TimeOut
ustawieniu procesy zaczynają umierać, a serwer zaczyna ponownie odpowiadać (w moim przypadku jest ustawiony do 45).
Moje pytanie: czy to oczekiwane zachowanie? Dlaczego Apache umiera, kiedy się osiąga MaxClients
? Jeśli działa z 24 połączeniami, czy nie powinno współpracować z 25, wystarczy poświęcić więcej czasu na odpowiedź na każde żądanie i ustawić w kolejce resztę?
Brzmi trochę dziwnie dla mnie, że każde uruchomione dziecko ab
może samodzielnie zabić serwer sieciowy, ustawiając równoczesne połączenia z serwerami MaxClients
.
źródło
To, co się tutaj dzieje, polega na tym, że masz 25 wątków zdolnych do akceptowania połączeń i wysyłasz 26 jednoczesnych żądań. To ostatnie żądanie znajduje się w kolejce gniazd w zależności od wielkości zaległości.
Drugi problem polega na tym, że cokolwiek uruchomisz, co zajmuje 2-3 sekundy, trwa wystarczająco długo, aby odpowiedzieć, że 25 równoczesnych połączeń spowalnia go. sleep (1) może działać, ale, gdy robisz blokowanie plików lub tabel z mysql, każde równoległe żądanie może czekać przed zakończeniem, aż osiągnie 45 sekundowy limit czasu.
23 MB wydaje się mały jak na proces apache z mod_php i załadowanymi modułami, więc podejrzewam, że te procesy apache mogą wymagać nieco więcej pamięci RAM w trakcie działania aplikacji. Naprawdę nie możesz robić matematyki z MaxClients i taką pamięcią ... będzie trochę blisko, ale nigdy nie wiadomo.
Jest jedna maszyna, procesy 56M i 49M.
inna maszyna:
inna maszyna:
Tak więc użycie pamięci jest bardzo zależne od zadania, które moduły są ładowane itp. Sądzę, że w dwóch ostatnich wyłącziliśmy pdo & pdo_mysql, ponieważ ta aplikacja ich nie używa.
Prawdziwe pytanie brzmi: co robisz, co zajmuje 3 sekundy? W dzisiejszym świecie jest to wieczność i uważana jest za aplikację „blokującą”. Apache zwykle nie umiera, ale pozostawia te wątki w kolejce zaległości, dopóki nie będzie w stanie ich obsłużyć lub upłynie limit czasu oczekiwania. Uważam, że Twoja aplikacja prawdopodobnie powoduje przekroczenie limitu czasu Apache. Wypróbuj na stronie zawierającej tylko phpinfo (); i sprawdź, czy wyniki są takie same.
źródło