Ограничение памяти для apache

Обновлено: 06.07.2024

Соответственно если нагрузка возрастает, то апач либо перестает успевать обрабатывать запросы либо система уходит в своп (в зависимости от MaxClients):
Сейчас в конфиге апача:

ListenBacklog 1024
StartServers 3
MinSpareServers 3
MaxSpareServers 5
ServerLimit 15
MaxClients 15
MaxRequestsPerChild 500

Загруженные модули:
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authn_alias_module modules/mod_authn_alias.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule file_cache_module modules/mod_file_cache.so
LoadModule cache_module modules/mod_cache.so
LoadModule include_module modules/mod_include.so
LoadModule filter_module modules/mod_filter.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule mime_module modules/mod_mime.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule info_module modules/mod_info.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule php5_module modules/libphp5.so
LoadModule rpaf_module modules/mod_rpaf-2.0.so

Собственно вопрос в том как бы сделать чтобы апач не потреблял столько памяти на процесс?

Главная

Типичная проблема с которой встречаются администраторы веб-серверов:

На сайт приходит шквал запросов, Apache занимает всю оперативную память и как только залазит в своп - до сайта не достучаться и даже на ssh зайти проблематично. Рано или поздно и swap закончится и. как думаете, что будет делать в ситуации когда программа просит памяти, а памяти нет?

А вот и нет :P, Linux начнет килять все процессы вподряд освобождая память (8.

cgroups_terminal_example.jpg

Есть стандартное средство - ограничение числа запущенных процессов Apache. Только надо заранее прикинуть сколько один процесс ОЗУ сожрет, и оставить 1-2 ГБ запаса. Проблема в том, что сколько апач сожрет памяти заранее может быть неизвестно и это число может плавать. Если ошибся - сервер завис. Если перестраховался - неоптимально расходуешь ресурсы.

Есть уже несколько лет другой способ ограничения ресурсов: cgroups или контрольные группы. Позволяет в весовом эквиваленте ограничивать утилизацию дисков (блочных устройств), памяти, сети, процессора и даже более тонкие штуки, вплоть до контроля в кеше какого ядра процессора держать данные. И привязывается это все на пользователя или на процессы.

Еще один плюс: ограничения работают на все что процесс породит. Т.е. мы можем зарезать Apache по памяти и нам уже не нужно считать сколько потомков он породит и сколько памяти они вместе сожрут.

В RHEL cgroups появились еще в 6 версии, а в 7 уже вовсю используются в системе инициализации systemd. Также на основе cgroups реализуется управление ресурсами в системах виртуаллизации, таких как docker и KVM.

Я буду работать, впрочем, с CentOS7 и опущу установку и сразу перейду к настройке. Дело в том, что в RHEL7 предлагается применять cgroups не так как написано в большинстве руководств по cgroups, включая руководство RHEL6. В RHEL7 для запуска используется systemd 205 и управление cgroups рекомендуется осуществлять через systemd, а не всюду описанным cgconfig. При этом именно в systemd 205 была отключена возможность тонкой настройки cgroups через ControlGroupAttribute и т.п. команды :).

Итак, хотим ограничивать процесс. Но в RHEL7 cgroups работают через systemd, а тот работает со службами, а не исполняемыми файлами. Поэтому натравливать cgroups будем на службы systemd:

Для ограничения занимаемого объема ОЗУ надо поставить, например, MemoryLimit=4096M

Если применяется php-fpm, то

Затем надо выполнить

И перезапустить сервис (т.к. cgroups нельзя применить к уже запущенным процессам)

systemctl stop php-fpm

systemctl start php-fpm

В cgroups есть работоспособный аналог команды nice. Надо установить:

По умолчанию CPUShares=1024 и приоритет можно понизить установив меньшее значение типа:

Конечно, вам уже хочется узнать какие еще команды есть? Смотрите в руководстве RHEL.

Лично я взялся за cgroups не из-за Apache или php-fpm. Начал тестировать кластерную файловую систему GlusterFS и, когда php-fpm выжирает всю память, файловая система начинает падать. Причем довольно хитро, в статусе показывая "все OK", всех пиров в кластере типа вижу, а по факту надо все перезагружать. Дополнительно на этой упавшей файловой системе как раз файлы лежат, необходимые для php-fpm, от чего php-fpm тоже подвисает не освобождая память и ситуация усугубляется.

Многие говорят, что веб-сервер Apache не обладает достаточной производительностью. Однако, это абсолютно не соответствует действительности. Данное мнение сложилось вследствие искажения оценки объективной особенности Apache – его работу и производительность необходимо скрупулёзно оптимизировать, что не так-то и просто. На самом деле Apache – это очень мощный и очень производительный веб-сервер. Да к тому же ещё так легко масштабируется и адаптируется к различным условиям применения. Однако, это всё в совокупности и является тормозящим фактором, сильно влияющим на производительность. В данной статье речь пойдёт о том, каким образом правильно и эффективно оптимизировать работу и производительность Apache без ущерба выбранной функциональности. Предлагаемые методы являются универсальными, допускается лишь незначительные различия в их реализации, в зависимости от используемой системы Linux.

Отключение неиспользуемых функций и модулей

По-умолчанию практически во всех популярных дистрибутивах Apache поставляется в универсальной комплектации, т. е. снабжён большим набором модулей. Это позволяет использовать его практически для любых веб-приложений.

Однако, если наблюдается недостаточная производительность или слишком большое потребление аппаратных ресурсов (как например памяти), следует выяснить, какие модули Apache для текущей конфигурации никогда не используются и даже не актуальны. Например, для современных, даже самых требовательных веб-приложений требуется не более 10-12 модулей. Не говоря уже о среднестатистических сайтах на WordPress или Drupal.

В данном случае определение и отключение ненужных модулей определяется в соответствии с требованиями для используемых веб-приложений, которые всегда заранее известны. Например, эти требования предоставляются самими разработчиками веб-приложений и доступны в открытом доступе. Также необходимо учитывать, что отключение модуля, который был определён как «неиспользуемый» явно, может негативно повлиять на работу других — «нужных» модулей, поскольку некоторые модули связаны между собой зависимостями. Поэтому при принятии решения об отключении тех или иных модулей необходимо отслеживать их зависимости. Эту информацию легко получить из официальной документации модуля, либо экспериментально. Во втором случае после отключения модуля и перезапуска Apache будет получена ошибка, как например:

В данном случае Apache использует модуль, который, в свою очередь, не может задействовать функционал, предоставляемый модулем dav_fs, который был отключен.
В Debian-системах, таких как Ubuntu, модули Apache хранятся в каталоге /etc/apache2/mods-available , а список включенных модулей — в каталоге /etc/apache2/mods-enabled . Отключение модуля выполняется путём удаления соответствующего файла в каталоге mods-enabled, либо можно использовать команду:

Аналогичным образом работает и команда включения модулей — a2enmod.

Самыми «прожорливыми» модулями Apache, потребляющими довольно много ресурсов системы являются: Rewrite, SSL, Phyton, PHP, Perl. Если они не используются, то конечно, их следует отключать. Либо заменять другими менее требовательными аналогами. Например, модуль Rewrite можно в большинстве случаев заменить модулем Alias.

Дело в том, что при использовании модуля php-fpm и ему подобных, изначально в памяти создаётся постоянный процесс для интерпретатора PHP ( Python или Ruby). И только после этого происходит перенаправление запросов от Apache к этому процессу для дальнейшей обработки. Таким образом, динамический контент обрабатывается всего двумя процессами. При этом потребление памяти может снизиться более чем в 8 раз.

Ограничение максимального количества процессов Apache

Как было показано выше, один дочерний процесс Apache может использовать 100 Мб RAM и выше. Когда таких процессов слишком много, память системы быстро будет исчерпана и веб-сервер начнёт «тормозить». В конфигурации по-умолчанию для Apache зарезервировано определённое количество процессов, например 30. Для не самого мощного сервера это может быть слишком много. Вообще этот параметр всегда важно тщательно подбирать для конкретной системы.

Для начала важно выяснить, сколько памяти требуется (с небольшим запасом) для корректной и стабильной работы веб-приложения. Затем нужно выделить большую часть свободной памяти веб-серверу. Ситуацию с памятью можно отследить, используя команду top, например:

Как можно видеть, в системе запущено 3 процесса Apache почти по 10 Мб (столбец RES) каждый. Ели этого много для используемой конфигурации, то целесообразно уменьшить количество процессов для одновременно обрабатываемых запросов. Это делается путём изменения соответствующего параметра (или параметров) работы мультипроцессингового модуля Apache – по-умолчанию это mpm_prefork. В системах Ubuntu соответствующий конфигурационный файл находится в /etc/apache2/mods-available и называется mpm_prefork.conf. Нужно изменить значение параметра MaxClients в соответствии с расчитанным значением объёма RAM, которое можно выделить Apache для данной системы. Например, по-умолчанию это значение обычно 25 — 30. Для не самого мощного сервера можно уменьшить до 15 (и даже меньше):

Теперь нужно перезагрузить Apache, чтобы сделанные настройки вступили в силу. Конечно, когда количество клиентов достигнет максимального количества, то пользователь просто получит ошибку сервера. Однако, он всегда может перезагрузить страницу и снова получить доступ к серверу (веб-приложению). Поскольку ограничение обслуживающих процессов не позволяет превысить лимит памяти, отведённой Apache, то это никак не скажется на его производительности. Ведь памяти всегда хватает. Это не совсем «демократично» по отношению к пользователям. Однако это лучше, чем бесконечно поддерживать «тормозящие» или полузависшие процессы Apache.

Использование альтернативных мультипроцессинговых модулей

Здесь нет чётких рекомендаций относительно того, кокой именно мультипроцессинговый модуль и для какой конфигурации использовать. Одни из них экономят процессорное время, другие — использование RAM.

Например, по-умолчанию Apache использует универсальный модуль mpm-prefork. Который работает практически со всеми интерпретаторами (PHP, Ruby и т. д.). Однако в качестве альтернативы можно использовать модуль mpm-worker. Который обладает более производительной стратегией управления дочерними процессами. Но данный модуль не поддерживает работу с интерпретаторами PHP и Ruby через стандартные внешние модули, такие как mod-php. Поэтому выбор мультипроцессингового модуля Apache – это очень выверенное и обдуманное решение.

Заключение

В заключение стоит ещё раз подчеркнуть, что веб-сервер Apache, вопреки устоявшемуся мнению, на самом деле очень мощная, универсальная и высокопроизводительная система с огромным потенциалом. Однако, его раскрытие напрямую зависит от грамотной и тонкой настройки и оптимизации всех компонентов веб-сервера.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Примечание: Некоторые рекомендации, перечисленные в этом руководстве, могут не сработать в новых версиях системы Ubuntu. Возможно, в настройке вам также пригодятся статьи:

Apache – очень производительный веб-сервер. Чтобы упростить начальную настройку, он предлагает большое количество предварительно установленных модулей. Потому Apache отлично подходит для развертывания новых проектов – с его помощью можно быстро настроить надежную среду производства. Однако по мере роста сайта (и, соответственно, объема трафика) вы можете столкнуться с проблемами.

Это руководство поможет увеличить производительность Apache на вашем виртуальном сервере.

1: Отключите ненужные модули

В Ubuntu и Debian-подобных системах есть каталоги etc/apache2/mods-enabled и /etc/apache2/mods-available/. В последнем хранится список всех модулей, установленных на данном сервере. А в каталоге mods-enabled находятся модули, включенные в данный момент.

Ситуация по умолчанию может отличаться на каждом сервере. Предположим, что на сервере по умолчанию включено 17 модулей. Как правило, этого слишком много для среднестатистического приложения. Кроме того, довольно сложно сразу определить ненужные модули, которые можно отключить, так как отдельные модули являются зависимостями других.

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

В Ubuntu и Debian модули отключаются с помощью этой команды:

sudo a2dismod autoindex

Отдельные модули потребляют очень много ресурсов; если вы не используете следующие модули, просто отключите их:

  • PHP
  • SSL
  • Rewrite
  • Perl
  • Python
  • Rack / Ruby / Passenger

Не все эти модули включены по умолчанию, однако ситуация индивидуальна для каждого сервера.

Примечание: Обычно Apache по умолчанию включает модуль rewrite, хотя его можно заменить модулем alias. Если вашему приложению подходит alias, отключите rewrite – это один из самых тяжелых модулей. Чтобы перейти с rewrite на alias, обратитесь к документации модуля. Даже если вы не сможете полностью отключить rewrite, вы сможете оптимизировать отдельные правила модуля.

Отключив модуль, перезапустите Apache, а затем проверьте лог ошибок, чтобы убедиться, что отключение модуля не навредило работе веб-сервера.

К примеру, вы можете получить такую ошибку:

Syntax error on line 6 of /etc/apache2/sites-enabled/site1:
Invalid command 'DAVLockDB', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.

Это значит, что отключенный модуль необходим для корректной работы веб-сервера. Включите его.

sudo a2enmod dav_fs

2: Переместите код

На сайтах PHP часто используется популярный модуль mod_php, а на сайтах ruby – Passenger Phusion (модули mod_rails или mod_rack).

Включение модуля mod_php может привести к тому, что на обслуживание одного дочернего процесса Apache будет требоваться 100 Мб RAM. Чем больше процессов Apache будет запущено на сервере, тем сложнее их будет обрабатывать.

Чтобы устранить эту проблему, можно использовать такие инструменты:

  • Для PHP можно установить php-fpm, который является отдельным процессом на основе протокола fastcgi.
  • В Python используйте uWSGI или gnunicorn
  • Для Rails используйте Unicorn.

Сначала запускается процесс для PHP, Python или Ruby, а затем Apache перенаправляет вызовы динамического контента на этот процесс вместо того, чтобы пытаться обработать его с помощью вложенного кода.

После удаления модуля mod_php размер процессов Apache может измениться с 90-120 Мб до всего 10 Мб. Весь динамический контент обслуживается всего двумя процессами на бэкэнде.

3: Ограничьте количество процессов Apache

Многие операционные системы используют конфигурации по умолчанию, которые не очень подходят маленьким серверам – 25 дочерних процессов. Если каждый дочерний процесс Apache требует 120 Мб RAM, то сервер будет тратить 3 Гб только на Apache.

Веб-браузер одного пользователя может запрашивать 4 элемента сайта за раз, а значит всего 7-8 человек способны перенагрузить сервер. Веб-страницы зависают или грузятся очень медленно.

Сервер часто поддерживает такие мертвые процессы Apache в активном состоянии, пытаясь обслужить запрашиваемый контент, а это снижает количество доступных процессов для обслуживания пользователей и объем памяти. В результате вы получаете плохой пользовательский опыт.

Определите, сколько RAM требуется вашему приложению и сколько памяти остается, а затем выделите большую часть оставшейся памяти для Apache.

К примеру, у вас есть три процесса php-fpm для обработки динамического контента, где каждый процесс использует до 70 Мб памяти, а также сервер MySQL, который берет до 120 Мб RAM. В результате получается, что приложение использует 330 Мб памяти. Если у вас маленький сервер, вы можете выделить для Apache около 150 Мб памяти.

Когда веб-сервер Apache запущен, запустите команду top. Она выводит множество полезной информации. Ниже приведен фрагмент ее результата:

top -bn 1
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
[. ] 15015 www-data 20 0 232m 9644 1900 S 0.0 1.6 0:00.02 apache2
15016 www-data 20 0 232m 9644 1900 S 0.0 1.6 0:00.01 apache2
15017 www-data 20 0 232m 9644 1900 S 0.0 1.6 0:00.02 apache2

Найдите значение в столбце RES для Apache (например, 9 644) и запишите его. На данный момент веб-сервер использует почти 10 Мб памяти. Если ограничить количество дочерних процессов Apache до 15, 150 Мб выделенной памяти будет вполне достаточно.

Отредактируйте конфигурационный файл Apache (в Ubuntu и Debian это /etc/apache2/apache2.confand) и найдите раздел mpm_prefork_module. Найдите строку MaxClients и введите 15, а затем сохраните файл и перезапустите веб-сервер.

<IfModule mpm_prefork_module>
StartServers 3
MinSpareServers 3
MaxSpareServers 5
MaxClients 30
MaxRequestsPerChild 0
</IfModule>

По умолчанию значение MaxClients может быть очень большим. Его нужно уменьшить.

Когда количество клиентов достигает предела, новые клиенты получат ошибку. Перезагрузив страницу, они смогут получить доступ к сайту.

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

В некоторых ситуациях меньшее количество дочерних процессов помогает увеличить производительность сервера.

4: Рассмотрите альтернативные конфигурации mpm.

Часто в конфигурациях Apache используется предварительная настройка prefork mpm, которая считается безопасной и подходящей для PHP и других языков.

Если вы избавитесь от внешних модулей (PHP или Rails), вы можете рассмотреть worker MPM в качестве альтернативы.

Чтобы включить этот модуль, введите:

sudo apt-get install apache2-mpm-worker
The following packages will be REMOVED:
apache2-mpm-prefork libapache2-mod-php5
The following NEW packages will be installed:
apache2-mpm-worker
0 upgraded, 1 newly installed, 2 to remove and 2 not upgraded.
Need to get 2,284 B of archives.
After this operation, 8,718 kB disk space will be freed.
Do you want to continue [Y/n]?

Внимание! В Ubuntu при установке модуля worker удаляется prefork mpm, mod_php и другие несовместимые модули.

Попробуйте применить эти рекомендации в комплексе на своем сервере производства.

Читайте также: