У нас есть сервер Apache, который почти ежедневно перестает отвечать на запросы. Проверяя / server-status (mod_status), мы видим, что у нас есть 60 дочерних процессов, которые все находятся в состоянии «W» (отправка ответа).
service httpd restart
все возвращается в норму, и проблема уходит на день или около того.max_exectution_time
установлен на «30».TimeOut
установлено на «60».curl_setopt($conn, CURLOPT_FORBID_REUSE, 0)
для запроса Solr (я надеюсь, что это правильно собирает мусор с помощью curl, если соединение разрывается).set_time_limit(0)
или что-нибудь подобное в нашем коде.set_time_limit
означает, что скрипты завершатся после max_execution_time
.У меня была теория, что Apache ListenBacklog
установлен слишком высоко, и что всякий раз, когда мы завершаем процессы, мгновенно запускались 60 новых, все пытались ответить клиентам, которые давно ушли. Это объясняет, почему проблема исчезла после перезапуска сервера. Но кажется ListenBacklog
не был установлен, и, следовательно, будет использоваться значение по умолчанию «511». Я пытался убить все дочерние процессы несколько раз подряд, чтобы очистить невыполненный журнал, но проблема остается ... все новые запросы к страницам PHP требуют бесконечного ответа (большинство не отвечает).
Конфигурация PHP:
max_execution_time = 30
max_input_time = 60
safe_mode = off
Конфигурация Apache:
KeepAlive off
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 60
MaxRequestsPerChild 1000
</IfModule>
У меня кончились идеи ... Будем признательны за любые подсказки!
Я бы рекомендовал следующие шаги по устранению неполадок:
strace -p $PID
на зависшем процессе, чтобы увидеть, какие системные вызовы, если таковые имеются, он застрялlsof -p $PID
в этом процессе, чтобы увидеть, могут ли открытые файловые дескрипторы или сокеты дать вам подсказкуtcpdump -vv -A -s1500 port 80
чтобы узнать, какой трафик и где не получается ответить.