Я выполняю веб-сервер Apache и хотел бы улучшиться немного, как ситуация OOM обрабатывается.
Я - avare очков OOM и уже сделал некоторые настройки в том вопросе поэтому, когда что-то плохо происходит, Linux уничтожает корректные процессы. Но недостаточно.
Проблема состоит в том, что иногда, когда OOM происходит, сервер перегружается и впоследствии отказывает и должен быть перезапущен. Я хотел бы обработать это без полного перезапуска сервера. Таким образом, я должен так или иначе "сцепить" сценарий на уничтожающем вызове OOM, который уничтожил бы всего апача (и его CGIs) процессы, таким образом освободив память и запустил бы его (Apache) снова.
Я знаю, что это работало бы, потому что, если OOM происходит и я достаточно быстр, чтобы войти в сервер и уничтожить Apache вручную, все в порядке затем.
К вашему сведению я выполняю теперь почти сто тех веб-серверов, вот почему я ищу полностью автоматическое решение.
Одно возможное решение состояло бы в том, чтобы, конечно, использовать некоторый сторожевой таймер, который проанализирует системный журнал и обнаружит OOMs этим способом - у меня уже есть что-то как этот, который уведомляет об уничтожениях OOM по электронной почте. Этот подход может решить некоторые ситуации, но если OOM действительно плох, сервер очень перегружается, и мой сценарий даже не запускается (его выполнение кроном). Это может быть улучшено при помощи inotify для наблюдения системного журнала или путем передачи по каналу системного журнала непосредственно (т.е. FIFO) к сценарию.
Но тем не менее я задаюсь вопросом - не там никакой путь, как "сцепить" сценарий непосредственно с уничтожителем OOM? Таким образом, я поместил бы что-то как этот в некотором/etc/.. файл:
oom_action="sh /path/to/my/script.sh kill"
Или просто не возможный сделать это как этот?
Я использую Centos 6, Apache 2.2 и PHP как FastCGI.
Поскольку я не нашел лучшего решения, я реализовал сторожевой таймер для чтения сообщений системного журнала ядра (через FIFO):
/etc/rsyslog.d:
(...)
kern.err |/path/to/fifo
и поиска в них Активность OOM-убийцы:
при чтении / path / to / fifo; do (..)
и когда OOM-убийца массово появляется (мне действительно нужно проверять только на случай чрезвычайной ситуации), я убиваю (и затем запускаю) Apache.
Я знаю, что существуют ужасные приложения PHP в дикой природе, их много, но разве нет чего-то , что вы могли бы сделать на стороне Apache / FastCGI / PHP? ? Постоянный OOMing Apache - это не то, с чем вы должны столкнуться очень часто.
Попробуйте уменьшить максимальное количество процессов Apache и обработчиков FastCGI и посмотрите, не слишком ли велики ваши текущие настройки php.ini для максимального объема памяти на скрипт.
Кроме того, вполне возможно использовать ulimit
с Apache и ограничить количество памяти, которую может использовать процесс. Это может помочь вам до того, как сервер чуть не погибнет.
OOM - крайнее средство, и все, что может к нему привести, должно быть проверено.
Почему бы вам просто не контролировать процессы apache и не установить для них oom_adj
значение 15, чтобы быть уверенными, что они первыми завершат работу при OOM? Здесь приведены некоторые инструкции по этому параметру.
В зависимости от вашей конфигурации вы можете либо изменить стартовые скрипты apache, либо настроить для этого простую задачу cron.
Вы также можете периодически просматривать вывод команда dmesg | grep -i oom
. Если будут какие-то строки, убийца OOM убил кого-то с момента последней загрузки сервера. Затем вы можете очистить буфер с помощью dmesg --clear
Думаю, лучше поместить свой процесс в подмножество памяти cgroup и использовать release_agent
для вызова внешнего скрипта, когда не хватает памяти
notify_on_release
contains a Boolean value, 1 or 0, that either enables or disables the execution of the release agent. If the notify_on_release is enabled, the kernel executes the contents of the release_agent file when a cgroup no longer contains any tasks (that is, the cgroup's tasks file contained some PIDs and those PIDs were removed, leaving the file empty). A path to the empty cgroup is provided as an argument to the release agent.
release_agent (present in the root cgroup only)
contains a command to be executed when a “notify on release” is triggered. Once a cgroup is emptied of all processes, and the notify_on_release flag is enabled, the kernel runs the command in the release_agent file and supplies it with a relative path (relative to the root cgroup) to the emptied cgroup as an argument. The release agent can be used, for example, to automatically remove empty cgroups
С помощью cgroup вы можете контролировать, сколько ресурсов вы можете использовать, и не перегружайте свой сервер
Using cgroup you can control the server resources