Dowiedz się, co faktycznie robi proces apache o wysokim zużyciu procesora?

18

Obecnie mamy kilka problemów z naszym serwerem, gdzie sporadycznie wydaje się, że otrzymujemy procesy Apache, które po prostu działają i działają, zajmując 100% procesora.

Podczas uruchamiania góry widzimy:

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
20788 www-data  20   0  318m  18m 3984 R  100  0.0  40:29.21 /usr/sbin/apache2 -k start
23523 www-data  20   0  319m  20m 4684 R  100  0.0   4:12.36 /usr/sbin/apache2 -k start

Chcę spróbować ustalić, co powoduje skrypt (lub cokolwiek to jest), więc próbowałem:

 strace -p 20788

Ale to wcale nie pokazuje żadnych wyników (zostawiłem je na około 10 minut i nic nie pokazuje). Z mojego zrozumienia może to oznaczać, że utknął w nieskończonej pętli i nie ma żadnych „wywołań systemowych” do wyświetlenia.

Czy jest coś jeszcze, co mogę zrobić, aby pokazać, co się dzieje?

Dzięki

Edycja - zapomniałem wspomnieć, że jest to serwer na żywo z kilkuset użytkownikami jednocześnie! Tak naprawdę nie mogę po prostu swobodnie próbować zmieniać opcji konfiguracji i restartować apache.

Edycja 2 - Śledzenie (bt) z gdb nie wydaje się tak przydatne, gdy PHP nie jest skonfigurowane z --enable-debug - pokazuje tylko „execute ()”, ale muszę wiedzieć, co to jest skrypt PHP faktycznie działa .. czy jest jakiś inny sposób?

#0  0x00007f6c143fb0c5 in ?? () from /usr/lib/apache2/modules/libphp5.so
#1  0x00007f6c143b040b in execute () from /usr/lib/apache2/modules/libphp5.so
#2  0x00007f6c1438b970 in zend_execute_scripts () from     /usr/lib/apache2/modules/libphp5.so
#3  0x00007f6c14337fe3 in php_execute_script () from     /usr/lib/apache2/modules/libphp5.so
#4  0x00007f6c1441ae7d in ?? () from /usr/lib/apache2/modules/libphp5.so
#5  0x00007f6c18912508 in ap_run_handler ()
#6  0x00007f6c1891297e in ap_invoke_handler ()
#7  0x00007f6c18922570 in ap_process_request ()
#8  0x00007f6c1891f398 in ?? ()
#9  0x00007f6c18918fa8 in ap_run_process_connection ()
#10 0x00007f6c189271d0 in ?? ()
#11 0x00007f6c1892793a in ?? ()
#12 0x00007f6c189284e7 in ap_mpm_run ()
#13 0x00007f6c188fd4a4 in main ()
BT643
źródło
1
Apache obsługuje „pełen wdzięku” restart, więc dlaczego byś tego nie zrobił?
poige
1
Myślę, że kiedy wypróbowaliśmy to wcześniej, nie mógł się z wdziękiem zrestartować z powodu „zablokowanych” procesów apache ... chociaż to może być źle, to było dawno temu.
BT643,
Inną sztuczką jest uruchomienie innej instancji apache na innym porcie, przekierowując do niego nowe połączenia.
poige 13.03.13

Odpowiedzi:

9

Cóż, jeśli czujesz się odważny:

gdb -p 20788

następnie wydaj, btaby zobaczyć ramkę stosu, na przykład

A tak przy okazji, ltracewarto wspomnieć - wypróbuj również.

UPD. : cóż, ok, skoro teraz mamy pomysł, że Apache naprawdę coś działa, dlaczego nie spojrzeć na mod_statuswynik - Rozszerzony ?

poige
źródło
gdb nie jest zainstalowany :( będę musiał poczekać, aż wrócę jutro do pracy, aby sprawdzić, czy mogę go zainstalować bez powodowania problemów .. ltraceteż nie pokazał żadnych danych wyjściowych.
BT643
Właśnie dodałem wyniki z gdb bt do początkowego postu ... tak naprawdę niewiele mi mówi!
BT643
Och, cieszę się, że zasugerowałem właściwy kierunek. )
poige
@ BT643, patrz UPD.
poige
4
Zrealizowany mod_status był już domyślnie włączony, był po prostu ograniczony do dostępu z wersji 127.0.0.1. Właśnie zalogowałem się przez SSH i przesłałem dane wyjściowe do pliku curl domain.com/server-status > randomfile.html- a następnie przejrzałem plik. Okazało się, że to stary kod programisty utknął w pętli (plik PHP)! Wszystko posortowane teraz. Dzięki za pomoc :)
BT643
2

Bardzo łatwym podejściem jest użycie htop. Możesz sortować według procesów o wysokim procesorze, a następnie użyć

  • dla straceprocesu
  • Chcę lsofzobaczyć otwarte pliki procesów
  • L do ltrace.

Odkryłem, że co najmniej jedna z tych opcji znajduje skrypt, który generuje obciążenie, i oczywiście można go użyć na produkcyjnym serwerze internetowym do debugowania.

znieść
źródło
1

Możesz spróbować:

  • iotop (pokazuje I / O w systemie)
  • netstat -t (pokazuje połączenia)
  • Spójrz na pliki dziennika apache i dowiedz się, co serwer zrobił ostatnio
  • ustaw niektóre limity RLimits dla procesu apache. Po osiągnięciu tych limitów proces zostanie zabity, dając ci więcej informacji
Kai Bojens
źródło
0

Twoje polecenie powinno działać, pod warunkiem że wykonasz żądanie HTTP, które wyzwala ten PID.

Może chcesz tymczasowo ponownie skonfigurować Apache za pomocą tylko jednego procesu potomnego?

Harry Slaughter
źródło
Należy pamiętać, że tylko jeden proces potomny oznacza, że ​​Apache może obsłużyć tylko jedno żądanie, a jeśli to jedno dziecko utknie, Apache nie będzie w stanie obsłużyć żadnych żądań.
Stefan Lasiewski
Nie można tego zrobić, ponieważ jest to serwer na żywo z setkami równoczesnych użytkowników (dodali to do PO, ponieważ wcześniej nie było to jasne)
BT643
0

PID tej instancji apache jest niski, może być ojcem całej partii. To z pewnością tłumaczy wysokie zużycie procesora (pozostaje w pobliżu, inne są odradzane i przywoływane zgodnie z obciążeniem). Dużo skumulowanego czasu procesora może po prostu oznaczać, że działał on przez długi czas. Brak danych wyjściowych strace(1)oznacza po prostu, że nie wywołał żadnych poleceń systemowych. Tak, może być w ciasnej pętli, ale apache jest w zasadzie we / wy przez sieć, więc sądzę, że nie robi nic pożytecznego. W każdym razie dziwne 100% jednego procesora.

vonbrand
źródło
Niski PID niekoniecznie oznacza, że ​​jest to stary proces. PID mają maksymalną wartość i owijają się, dzięki czemu można tworzyć nowe procesy przy użyciu niskich PID.
austin
0

Spróbuj tego:

1) Uruchom dziennik z datą / godziną, skryptem PHP i identyfikatorem PID getmypid()

2) Następnie obserwuj swój serwer za pomocą top

3) Gdy zobaczysz, że proces apache idzie w górę, wyszukaj w dziennikach tę samą datę / godzinę i PID. Powinieneś być w stanie znaleźć problematyczny skrypt.

feniks
źródło
To ciekawe rozwiązanie, ale widzę, że pochłania więcej zasobów, niż jest to warte, biorąc pod uwagę, że mod_statusrobi to całkiem dobrze.
austin