Ошибка httpd prefork invoked oom killer или почему падает Apache?
Ссылки по теме настроек Apache
<callout type="info">Также в wiki есть отдельная статья про OOM.</callout>
TL;DR не использовать дефолтные настройки Apache (MaxClients 256 на сервере с 1 ГБ RAM прямой путь к OOM). Совет не использовать Apache и перейти на nginx не будем рассматривать, потому-что нельзя ездить на Камаро в поле и на Белазе по автобану.
Итак, начинаем с подсчёта потребления памяти одним процессом Apache. В этом нам поможет скрипт ps_mem
# ps_mem Private + Shared = RAM used Program 2.0 MiB + 97.0 KiB = 2.1 MiB proftpd 14.5 MiB + 6.7 MiB = 21.2 MiB nginx (5) 7.2 MiB + 26.4 MiB = 33.6 MiB httpd (44) 327.9 MiB + 271.5 KiB = 328.2 MiB mysqld --------------------------------- 577.0 MiB =================================
Не забываем, о том как Linux считает память
У нас 44 процесса Apache, общее потребление памяти 328 МБ, а один процесс занимает 26 МБ (без опкэша было бы сильно больше). На сервере доступно 4 ГБ памяти. Скрипт mysqltuner.pl уверенно сообщает, что максимальное количество памяти, которое он может использовать 1 ГБ.
Округлим 26 МБ до 32 для удобства восприятия. В итоге формула получается такая: Объём RAM минус резерв для MySQL минус резерв для других процессов и всё это делим на память одного процесса Apache.
То есть: (4096 - 1024 - 512) / 32 = 80
MaxClients и ServerLimit можем поставить равным 80. Естественно эта формула очень условная и надо учитывать особенности конкретной системы.
Есть также замечательные скрипты, которые сразу подскажут какие значения лучше поставить - apachebuddy.pl и apache2buddy.pl, apache2buddy.
Первый скрипт работает с Apache 2.2. Второй для Apache 2.4
Важное замечание по опции MaxRequestsPerChild
Setting MaxRequestsPerChild to a non-zero limit solves some memory-leakage problems caused by sloppy programming practices and bugs, whereby a child process consumes a little more memory after each request. In such cases, and where the directive is left unbounded, after a certain number of requests the children will use up all the available memory and the server will die from memory starvation.
И еще интересная теория насчёт значений для других опций
- StartServers: 30% of MaxClients
- MinSpareServers: 5% of MaxClients
- MaxSpareServers: 10% of MaxClients
- MaxRequestWorkers = MaxClients
- MaxConnectionsPerChild= 10000 (To avoid problem with memory leaks in WordPress plugin themes and apps)
При существенной нагрузке в /var/log/httpd/error_log
можно увидеть ошибку server reached MaxClients setting, consider raising the MaxClients setting. Как нетрудно догадаться в этом случае нужно увеличить значение для MaxClients
если есть достаточно RAM.
Еще важный момент. В CentOS 6 настройки находятся в /etc/httpd/conf/httpd.conf
, в Debian/Ubuntu в файле /etc/apache2/conf/apache2.conf
, а вот в CentOS 7 нужно редактировать файл /etc/httpd/conf.d/mpm_prefork.conf
.
И последнее замечание - если вы поменяли MaxClients
, а настройки не вступили в силу, то значит опция определена где-то ещё. Найти такие файлы можно командой
# find /etc -type f -exec grep -l 'MaxClients' {} \;
или
# grep -iRl "MaxClients" /etc/
Впрочем, это уже совсем другая история.
EOM
Обсуждение