Jak debugować limity czasu Apache?

14

Korzystam z aplikacji PHP na serwerze Apache 2.2 (Ubuntu Server 10.04, 8x2GHz, 12Gb RAM) przy użyciu prefork. Każdego dnia Apache otrzymuje około 100–200 tys. Żądań, z czego około 100–200 przekracza limit czasu (czyli około 1 na tysiąc), prawie wszystkie pozostałe żądania są obsługiwane znacznie poniżej limitu czasu.

Co mogę zrobić, aby dowiedzieć się, dlaczego tak się dzieje? Czy to normalne, że niektóre małe części wszystkich żądań przekraczają limit czasu?

Oto co zrobiłem do tej pory:

Żąda czasu odpowiedzi

Jak widać, jest bardzo niewiele żądań, które znajdują się między limitem czasu a bardziej uzasadnionym żądaniem. Obecnie limit czasu ustawiony jest na 50 sekund, poprzednio był ustawiony na 300 i nadal była taka sama sytuacja z niektórymi limitami czasu, a następnie ogromną luką w stosunku do innych żądań.

Wszystkie żądania, które przekroczą limit czasu, są AJAXwnioskami, ale znaczna większość z nich jest, więc może to bardziej zbieg okoliczności. Kod powrotu Apache jest 200, ale limit czasu został wyraźnie osiągnięty. Pochodzą z szerokiej gamy różnych adresów IP.

Przejrzałem prośby, które wygasły, i nie ma w nich nic specjalnego, jeśli wykonam te same prośby, które spełnią w niecałą sekundę.

Próbowałem spojrzeć na różne zasoby, aby sprawdzić, czy mogę znaleźć przyczynę, ale bez powodzenia. Zawsze jest dużo wolnej pamięci (minimum około 3 GB wolnej przestrzeni), obciążenie czasami dochodzi nawet do 1,4, a wykorzystanie procesora do 40%, ale wiele limitów czasu występuje, gdy obciążenie i wykorzystanie procesora są niskie. Zapis / odczyt dysku jest prawie stały w ciągu dnia. W dzienniku powolnych zapytań MySQL nie ma wpisów (ustawione na rejestrowanie czegokolwiek powyżej 1 sekundy), żadne żądanie nie korzysta z tylu zapisów / odczytów bazy danych.

Żądaj czasu odpowiedzi przy obciążeniu systemu / jednostce centralnej

Kolor niebieski oznacza wykorzystanie procesora, które osiąga wartość szczytową przy 40%, bordowy jest obciążony wartością szczytową przy 1,4. Widzimy więc, że mamy limity czasu nawet przy niskim zużyciu / obciążeniu procesora (dziesięciosekundowe skoki dobrze odpowiadają zużyciu procesora, ale to kolejny problem, mam większą nadzieję dowiedzieć się, co może być przyczyną).

Dziennik błędów Apache nie zawiera błędów i nie widziałem, aby osiągnął więcej niż 200 aktywnych procesów Apache.

Ustawienia serwera:

Timeout 50 
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

<IfModule mpm_prefork_module>
    ServerLimit     350
    StartServers        20
    MinSpareServers     75
    MaxSpareServers     150
    MaxClients          320
    MaxRequestsPerChild 5000
</IfModule>

Aktualizacja:

Zaktualizowałem do Ubuntu 12.04.1, na wszelki wypadek, bez zmian. Dodałem mod_reqtimeout z ustawieniami:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Teraz prawie wszystkie limity czasu mają miejsce po 10 sekundach, jeden lub dwa po 20 sekundach. Rozumiem, że oznacza to, że przez większość czasu otrzymywanie treści żądania jest problematyczne? Treść żądania nigdy nie powinna być większa niż kilkaset bajtów. Monitorowałem ruch sieciowy co 1 sekundę i nigdy nie wzrasta on powyżej 1 Mb / s i nie widzę żadnych sygnałów rxerr ani rxdorps, biorąc pod uwagę, że serwer znajduje się na linii 1 Gbit / s, co nie brzmi jak HopelessN00b napisał o. Czy może to być tylko przypadek złych połączeń użytkownika?

W przypadku skoków co godzinę (wydają się nieco dryfować, na wykresach powyżej są one 33 minuty po godzinie, teraz są za 12 minut), próbowałem sprawdzić, czy coś okresowo działa ( crons itp.), ale nic nie znalazł. Odśmiecanie PHP działa dwa razy co godzinę, ale nie w czasie szczytów, wciąż próbowałem go wyłączyć, ale to nie robi różnicy.

Użyłem dstat z opcją --top-cpu i top, aby spojrzeć na procesy w czasie szczytów, a wszystko, co się pokazuje, to apache pracujący przez kilka sekund, ale żaden inny proces nie używa znacznej mocy procesora.

Zrobiłem powiększony wykres skoków: Skrócony czas odpowiedzi na zapytanie

Dla mnie wygląda na to, że Apache zatrzymuje się na kilka sekund, a następnie ciężko pracuje, aby przetworzyć żądania, które pojawiły się podczas zatrzymania. Co może spowodować taki postój, czy też źle go interpretuję?

Leon
źródło
1
Chciałem zamieścić post z niektórymi wykresami dotyczącymi próśb, ale mój przedstawiciel jest zbyt niski.
Leon

Odpowiedzi:

4

Pierwszą rzeczą, którą zauważam, patrząc na twój pierwszy wykres, wydaje się być cogodzinne spowolnienie (występujące około 40 minut po godzinie), które może przyczyniać się do problemu. Powinieneś spojrzeć na harmonogramy zadań w systemie operacyjnym / bazie danych.

Na podstawie dostarczonych danych moim następnym krokiem będzie przyjrzenie się częstotliwości czasów odpowiedzi (liczba odpowiedzi na osi Y w porównaniu do czasu trwania na X), ale tylko w tym adresy URL, które wykazują limit czasu (lub najlepiej jeden adres URL na raz ). W typowym systemie powinno to być zgodne z rozkładem normalnym lub rozkładem Poissona - żądania, które przekroczą limit czasu, mogą po prostu stanowić część ogona - w takim przypadku musisz skoncentrować swoje wysiłki na ogólnym strojeniu. OTOH, jeśli dystrybucja jest bimodalna, musisz poszukać rywalizacji gdzieś w kodzie.

symcbean
źródło
Dzięki za twoją odpowiedź. Sprawdzam, co może powodować godzinne spowolnienie. W międzyczasie wykonałem wykres częstotliwości danych, które już mam. To tylko jeden z adresów URL, który ma problem z przekroczeniem limitu czasu (ale pozostałe wyglądają bardzo podobnie): leela.kikora.no/apache_hist_show.png Limit czasu jest bardzo mały w porównaniu do tych, które zajmują mniej niż 10 sekund, ale wygląda na to, że jakby to nie mogło być częścią ogona. Ale z drugiej strony może być tak, że ponieważ reprezentują wszystko, co zajęłoby ponad 50 sekund, powinno to wyglądać tak.
Leon
3

Zastanawiam się nad tym, biorąc pod uwagę fakt, że otrzymujesz dużą liczbę żądań dziennie i wydaje się, że masz limity czasu tylko w godzinach szczytu (z zamieszczonych zdjęć).

Na blogu o awariach serwera jest postPer Second Measurements Don't Cut It ... czy jest możliwe, że niektóre z tych żądań napotkały ten sam problem, na który wpadł zespół ServerFault?

Odkryliśmy, że dość często odrzucamy pakiety na interfejsach 1 Gbit / s z szybkością zaledwie 10-30 MBit / s, co negatywnie wpływa na naszą wydajność. Wynika to z faktu, że szybkość 10–30 MBit / s to tak naprawdę liczba bitów przesyłanych w ciągu 5 minut konwertowanych na szybkość jednej sekundy. Kiedy kopaliśmy bliżej za pomocą Wireshark i korzystaliśmy z wykresu IO o wartości milisekundy, widzieliśmy, że często rozrywamy szybkość 1 Mbit na milisekundę tak zwanych interfejsów 1 Gbit / s.

Beznadziejny
źródło
Interesujące, spojrzę na to. Włączyłem mod_reqtimeout i ustawiłem na nagłówek RequestReadTimeout = 20-40, minrate = 500 i RequestReadTimeout body = 10, minrate = 500 i prawie wszystkie limity czasu mają miejsce teraz o 10 sekundach. Rozumiem, że oznacza to, że treść żądania trwa zbyt długo (treść nie powinna nigdy przekraczać więcej niż kilkaset bajtów), więc albo niektórzy z moich użytkowników mają złe połączenia, albo, jak mówisz, pewne zatory po stronie mojego serwera.
Leon