Сегодня я перезапустил свой демон 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, приблизительную информацию здесь:
- Выполняется: это состояние, когда процесс либо запущен, либо готов к запуску.
- Прерываемый: это состояние является заблокированным состоянием процесса, который ожидает события или сигнала от другого процесса.
- Бесперебойность: это также заблокированное состояние. Процесс принудительно останавливается при определенных условиях, когда ожидается состояние оборудования и сигнал не может быть обработан.
- Остановлен: это состояние возникает по завершении процесса. Этот процесс можно перезапустить
- Зомби: в этом состоянии процесс будет остановлен, а информация останется доступной в таблице процессов.
Однако если это происходит во время регулярного использования вашего веб-сервера (в конце концов, мы говорим о процессах php), вы можете временно исправить это с помощью cronjob каждую минуту, выполняя изящный перезапуск apache (service apache2 reload
), но это не решает основную проблему, поедающую ваши доступные слоты.
Во втором случае вам нужно определить, какой хостинг вызывает зомби, и приложение должно быть исправлено. 99% таких зомби вызваны плохо запрограммированными веб-сайтами.