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

Апач умер; Подозреваемый не имеет ограничений, но не может воспроизвести

Апач умер вчера вечером. Журнал ошибок показывает это

[alert] (11)Resource temporarily unavailable: setuid: unable to change to uid: 48

Просматривая Интернет, кажется, что все говорят, что это проблема ulimit в Linux. Если я правильно понимаю, ulimit по умолчанию ограничивает количество одновременных процессов для любого пользователя без полномочий root до 1024. Если это максимальное число для пользователя (в данном случае apache) достигнуто, он не сможет создать больше процессов. Таким образом объясняется, почему он не может установить uid для пользователя apache, когда он попытался создать нового дочернего элемента.

Вчера вечером пользователь нашего веб-приложения сделал 1100+ запросов GET к одной и той же странице примерно за 1 минуту, и именно тогда сервер умер.

В моем конфигурационном файле Apache есть следующее:

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      2000
MaxClients       2000
MaxRequestsPerChild  4000
</IfModule>

KeepAlive On
MaxKeepAliveTimeout 5
KeepAliveTimeout 5

Если мой MaxClients равен 2000, а MaxSpareServers равен 20, то это означает, что для того, чтобы Apache достиг ulimit для процессов, он должен был иметь 1000+ занятый процессы, которых я просто не вижу, учитывая, что эти GET-запросы были крошечными и могли легко обрабатывать 20-30 запросов в секунду. Вдобавок к этому MaxRequestsPerChild имеет значение 4000, поэтому он не должен порождать так много новых детей, верно? Так был ulimit действительно виноват здесь в том, почему он не может установить?

Я использовал Apache ab инструмент, чтобы попытаться воспроизвести это на гораздо менее мощной локальной сборке, и я не могу. Даже менее мощное оборудование может обрабатывать тысячи подключений за одну минуту с хорошо производительность. Если я одновременно попытаюсь получить доступ к серверу через Интернет, это станет медленным, но Apache не упадет.

Итак, вот мои вопросы:

  1. Есть ли лучший способ настроить модуль prefork? Мы только что перешли со старого сервера на новый. В старшей версии ServerLimit и MaxClients были установлены на 512. Я подумал, что с таким же успехом можно было бы установить его на 2000, чтобы избежать повторного изменения в обозримом будущем.
  2. Я попытался настроить ulimit nproc на НИЗКОЕ число, чтобы попытаться воспроизвести ошибку. В limits.conf я установил * hard nproc 15, но Apache по-прежнему порождает около 30 детей, когда я запускаю ab. Я что-то упускаю?
  3. Несмотря на номер 2, можно ли поднять параметр nproc до значения выше 10000?
  4. Я также хотел бы реализовать что-то, что помешает пользователям делать так много попыток. В прошлом я использовал iptables для блокировки пользователей, сделавших более 5 SSH-запросов за минуту. Я думал о том, чтобы сделать что-то подобное для HTTP-запросов, но хотел узнать, есть ли лучшие решения. Я слышал о fail2ban, mod_security и т. Д., Но не уверен, что они делают. Принесут ли они мне пользу в этом случае? Есть другие предложения?

Информация о сервере: RHEL 6.3, Apache 2.2.15