Назад | Перейти на главную страницу

Слишком много зомби-процессов PHP

Сегодня я перезапустил свой демон apache, чтобы перезагрузить файл конфигурации, но после этого я начал видеть в системе множество процессов зомби php. Количество варьируется от 10 до 30, и все они потребляют небольшую долю процессора, пока умирают. С чего начать отладку этой проблемы?

Модификация, которую я сделал, заключалась в уменьшении максимального числа запросов на ребенка с 0 (массовые утечки памяти) до 1000. Я думаю, что процессы php происходят из сценария, который получает данные от «глупых» устройств, т.е. они отправляют запрос с параметрами GET и не заботятся о результате.

Некоторые данные:

uname -a

# uname -a
Linux <hostname> 2.6.32-71.29.1.el6.x86_64 #1 SMP Mon Jun 27 19:49:27 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

ps -aux | grep php

# ps aux | grep php
user1     5709  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5717  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5721  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5722  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5723  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5724  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5725  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5729  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5731  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5737  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5760  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5778  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5793  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5798  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5800  1.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5833  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5850  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5870  3.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5875  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5876  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5877  2.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5886  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5926  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5939  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5941  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5961  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5962  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5973  0.0  0.0      0     0 ?        Z    12:15   0:00 [php] <defunct>
user1     5977  0.0  0.2 106836  8680 ?        R    12:15   0:00 /usr/bin/php /home/user1/public_html/<script>.php
root      5981  0.0  0.0 103228   836 pts/0    S+   12:15   0:00 grep php

свободно

# free -m
             total       used       free     shared    buffers     cached
Mem:          3831       3173        658          0        183       2502
-/+ buffers/cache:        487       3344
Swap:         4031          7       4024

время безотказной работы

# uptime
 12:18:10 up 105 days, 23:21,  1 user,  load average: 0.23, 0.20, 0.18

Что-нибудь еще нужно, чтобы помочь мне отладить это?

Это не проблема. Зомби не занимают ни процессор, ни память, ни что-либо кроме слотов таблицы процессов. Вы сказали, что зомби не торчат очень долго, поэтому все, что происходит, - это то, что главный процесс Apache делает что-то, кроме ожидания выхода дочерних процессов, поэтому иногда требуется некоторое время, прежде чем завершится дети пожинают.

Добавьте код pcntl_wait () после разветвления процесса с помощью pcntl_fork ()

$pid = pcntl_wait($status, WNOHANG);
int pcntl_wait ( int &$status [, int $options ] )

В wait Функция приостанавливает выполнение текущего процесса до тех пор, пока дочерний процесс не выйдет, или пока не будет доставлен сигнал, действие которого должно завершить текущий процесс или вызвать функцию обработки сигнала. Если к моменту вызова ребенок уже вышел (так называемый «зомби-процесс»), функция немедленно возвращается. Освобождаются любые системные ресурсы, используемые ребенком.

Процесс зомби - это просто процесс, родитель которого уже умер / был убит и еще не был приведен в порядок.

Если это происходит во время перезапуска службы, это нормально. Вы должны прочитать о состояниях процессов Linux, приблизительную информацию здесь:

  1. Выполняется: это состояние, когда процесс либо запущен, либо готов к запуску.
  2. Прерываемый: это состояние является заблокированным состоянием процесса, который ожидает события или сигнала от другого процесса.
  3. Бесперебойность: это также заблокированное состояние. Процесс принудительно останавливается при определенных условиях, когда ожидается состояние оборудования и сигнал не может быть обработан.
  4. Остановлен: это состояние возникает по завершении процесса. Этот процесс можно перезапустить
  5. Зомби: в этом состоянии процесс будет остановлен, а информация останется доступной в таблице процессов.

Однако если это происходит во время регулярного использования вашего веб-сервера (в конце концов, мы говорим о процессах php), вы можете временно исправить это с помощью cronjob каждую минуту, выполняя изящный перезапуск apache (service apache2 reload), но это не решает основную проблему, поедающую ваши доступные слоты.

Во втором случае вам нужно определить, какой хостинг вызывает зомби, и приложение должно быть исправлено. 99% таких зомби вызваны плохо запрограммированными веб-сайтами.