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

Проблема с производительностью Apache: после «1000 детей» Apache больше не отвечает на HTTP-запросы. Не проблема с MaxClients?

Надеясь, что кто-то может указать мне правильное направление, поскольку последнюю неделю я потратил, пытаясь выяснить, в чем «проблема», но не смог, попытался отправить сообщение в списки рассылки пользователей Apache, но хотел отразить его здесь также.

Запуск Apache 2.2.3 mod_php на CentOS 5.8.

В то же время каждый день, когда трафик высок, у нас возникает проблема, когда Apache больше не отвечает на какие-либо HTTP-запросы.

Это звучало как стандартная проблема с MaxClients, но, похоже, это не так.

Кроме того, при входе в систему в это время средняя загрузка ниже 1, а оперативной памяти все еще достаточно.

Просматривая / var / log / httpd / error_log, я заметил следующие закономерности:

[Mon Apr 30 07:00:34 2012] [info] server seems busy, (you may need to increaseStartServers, or Min/MaxSpareServers), spawning 32 children, there are 0 idle, and 905 total children
[Mon Apr 30 07:00:35 2012] [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 32 children, there are 0 idle, and 937 total children
[Mon Apr 30 07:00:36 2012] [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 32 children, there are 0 idle, and 969 total children
[Mon Apr 30 07:00:37 2012] [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 32 children, there are 35 idle, and 1001 total children

[Mon Apr 30 07:00:42 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>
[Mon Apr 30 07:00:49 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>
[Mon Apr 30 07:00:56 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>
[Mon Apr 30 07:01:03 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>

Несколько раз в день сразу после 1000 total children Apache перестает отвечать, и его необходимо перезапустить, чтобы снова заработать.

Я просмотрел error_log несколько недель назад, и это та же картина, сервер достигает 1000 дочерних элементов, а затем сразу же выплевывает [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 сообщение об ошибке и перестает отвечать.

Однако нагрузка на сервер довольно низкая ... Даже если я попытаюсь запросить простой файл index.html, время истечет.

Вот соответствующий раздел из конфига:

Timeout 45
KeepAlive On
MaxKeepAliveRequests 10000
KeepAliveTimeout 3

<IfModule prefork.c>
StartServers      80
MinSpareServers   50
MaxSpareServers  120
ServerLimit     3500
MaxClients      3500
MaxRequestsPerChild  2000
</IfModule>

Кто-нибудь знает, почему магическое количество детей, которых Apache может достичь, составляет 1000, прежде чем он перестанет обрабатывать больше запросов?

Или как разобраться в (70007)The timeout specified has expired: connect to listener on [::]:80 сообщение?

О каком «указанном тайм-ауте» идет речь?

Я дважды проверил Max Open Files, раньше он был 1024, но теперь его 16384, все та же проблема.

Это долгий путь, но у меня были такие проблемы. Я точно не помню, что это было за сообщение об ошибке, но причиной проблемы всегда была ошибочная программа PHP, которая создавала рекурсивные запросы (т.е. программа запрашивает URL-адрес, который, в свою очередь, повторно запрашивает тот же URL-адрес и т. Д.). Я видел это, например, в связи с ErrorDocument settings, где документ, который должен был обработать ошибку, был ошибочным или отсутствовал и который вызвал ошибку.

Вы можете легко проверить, может ли это быть проблемой в вашем журнале access.log: у вас должно быть много запросов с IP-адреса вашего сервера, и все это за очень короткое время. Это работает, пока вы не нажмете настройку MaxClients или пока в вашей системе не закончатся ресурсы. Единственное решение - исправить рассматриваемую программу PHP.

Проверьте, включен ли KeepAlive Apache и каково значение KeepAliveTimeout. На самом деле это не должно быть больше 3 секунд. Он сохранит конкретный процесс / поток, назначенный клиенту на это время.

Затем выполните команду grep httpd conf dir для 1000, чтобы узнать, установлен ли где-то этот номер.

grep -r '1000' /etc/httpd/conf
grep -r '1000' /etc/httpd/conf.d

Кроме того, это может быть случай, когда ваш php-код (ошибочно) поддерживает каждый процесс / поток, который обрабатывает его, на неопределенный срок, и у вас их заканчиваются.

Timeout 45 

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

http://httpd.apache.org/docs/2.1/mod/core.html#timeout

Может быть, также проверьте эту страницу, чтобы узнать об общих проблемах с производительностью?

http://httpd.apache.org/docs/current/misc/perf-tuning.html