Как мне корректно завершить работу веб-сервера Mongrel

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

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

В идеале я хочу отправить Mongrel сигнал, который говорит: «Закончи все, что ты делаешь, а затем уйди, прежде чем принимать какие-либо соединения».

Есть ли для этого стандартный метод или передовой опыт?


person AndrewR    schedule 26.08.2008    source источник


Ответы (6)


Я провел немного больше исследований в источнике Mongrel, и оказалось, что Mongrel устанавливает обработчик сигналов, чтобы перехватить стандартное уничтожение процесса (TERM) и выполнить корректное завершение работы, так что в конце концов мне не нужна особая процедура.

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

** TERM signal received.
Thu Aug 28 00:52:35 +0000 2008: Reaping 2 threads for slow workers because of 'shutdown'
Waiting for 2 requests to finish, could take 60 seconds.Thu Aug 28 00:52:41 +0000 2008: Reaping 2 threads for slow workers because of 'shutdown'
Waiting for 2 requests to finish, could take 60 seconds.Thu Aug 28 00:52:43 +0000 2008 (13051) Rendering layoutfalsecontent_typetext/htmlactionindex within layouts/application
person AndrewR    schedule 28.08.2008
comment
Если вы откажетесь принять другой, по крайней мере, он будет правильно заказан в первую очередь с этим. - person Otto; 14.12.2008

Посмотрите на использование monit. Вы можете динамически перезапускать mongrel в зависимости от использования памяти или процессора. Вот строка из конфигурационного файла, который я написал для своего клиента.

check process mongrel-8000 with pidfile /var/www/apps/fooapp/current/tmp/pids/mongrel.8000.pid
    start program = "/usr/local/bin/mongrel_rails cluster::start --only 8000"
    stop program = "/usr/local/bin/mongrel_rails cluster::stop --only 8000"

    if totalmem is greater than 150.0 MB for 5 cycles then restart       # eating up memory?
    if cpu is greater than 50% for 8 cycles then alert                  # send an email to admin
    if cpu is greater than 80% for 5 cycles then restart                # hung process?
    if loadavg(5min) greater than 10 for 3 cycles then restart          # bad, bad, bad
    if 3 restarts within 5 cycles then timeout                         # something is wrong, call the sys-admin

    if failed host 192.168.106.53 port 8000 protocol http request /monit_stub
        with timeout 10 seconds
        then restart
    group mongrel

Затем вы должны повторить эту конфигурацию для всех экземпляров вашего беспородного кластера. Строка monit_stub - это просто пустой файл, который monit пытается загрузить. Если не может, он также пытается перезапустить экземпляр.

Примечание: мониторинг ресурсов, похоже, не работает в OS X с ядром Darwin.

person hoyhoy    schedule 29.08.2008

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

www.modrails.com значительно сократил объем используемой памяти

person TonyLa    schedule 27.08.2008
comment
modrails только уменьшает общий объем памяти. Он не устраняет утечки памяти, которые, вероятно, являются основной причиной необходимости перезапуска дворняг. - person ryantm; 30.09.2008

Болотный:

Если у вас запущен один процесс, он будет корректно завершен (обслужите все запросы в своей очереди, которая должна быть только 1, если вы используете правильную балансировку нагрузки). Проблема в том, что вы не можете запустить новый сервер, пока старый не умрет, поэтому ваши пользователи будут стоять в очереди в балансировщике нагрузки. Что я нашел успешным, так это «каскадный» или непрерывный перезапуск дворняг. Вместо того, чтобы останавливать их все и запускать их все (то есть ставить запросы в очередь до тех пор, пока одна дворняга не будет завершена, остановлена, перезапущена и принимает соединения), вы можете остановить, а затем запустить каждую дворнягу последовательно, заблокировав вызов для перезапуска следующей дворняги, пока предыдущий не будет резервное копирование (используйте настоящую HTTP-проверку контроллера / status). По мере того, как ваши дворняги катятся, только один из них выходит из строя, и вы обслуживаете две базы кода - если вы не можете этого сделать, вам следует на минуту открыть страницу обслуживания. Вы должны иметь возможность автоматизировать это с помощью capistrano или любого другого инструмента развертывания.

Итак, у меня есть 3 задачи: cap: deploy - который выполняет традиционный метод одновременного перезапуска с помощью ловушки, которая создает страницу обслуживания и затем отключает ее после проверки HTTP. cap: deploy: Rolling - который выполняет этот каскад по всей машине (я извлекаю из iClassify, чтобы узнать, сколько дворняг находится на данной машине) без страницы обслуживания. cap deploy: migrations - это страница обслуживания + миграции, поскольку запускать миграции «вживую» обычно - плохая идея.

person Community    schedule 05.02.2009

Попробуйте использовать:

mongrel_cluster_ctl stop

Вы также можете использовать:

mongrel_cluster_ctl restart
person John Topley    schedule 26.08.2008

есть вопрос

что происходит, когда срабатывает / usr / local / bin / mongrel_rails cluster :: start --only 8000?

все ли запросы обслуживаются этим конкретным процессом до конца? или они прерваны?

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

person Community    schedule 14.12.2008