Есть ли в Интернете примеры того, как отслеживать delayed_job с помощью Monit?

Все, что я могу найти, использует Бога, но я отказываюсь использовать Бога, поскольку долго выполняющиеся процессы в Ruby обычно отстой. (Самый последний пост в списке рассылки Бога? Использование памяти Бога неуклонно растет < / а>.)

Обновление: delayed_job теперь поставляется с образцом конфигурации мониторинга на основании этого вопроса.

74
Luke Francl 4 Авг 2009 в 12:30

13 ответов

Лучший ответ

Вот как у меня это работает.

  1. Используйте коллективную идею delayed_job, помимо активной поддержки, в этой версии есть отличный демон script/delayed_job вы можете использовать с monit. В Railscasts есть хороший выпуск об этой версии delayed_job (версия ASCIICasts). Этот скрипт также имеет некоторые другие полезные функции, такие как возможность запускать несколько рабочих процессов. Я не говорю об этом здесь.
  2. Установите monit. Я установил из исходников, потому что версия Ubuntu до смешного устарела. Я выполнил эти инструкции, чтобы получить стандартные сценарии init.d, которые поставляются с пакетами Ubuntu. Мне также нужно было выполнить настройку с помощью ./configure --sysconfdir=/etc/monit, чтобы был выбран стандартный каталог конфигурации Ubuntu.
  3. Напишите сценарий мониторинга. Вот что я придумал:

    check process delayed_job with pidfile /var/www/app/shared/pids/delayed_job.pid
    start program = "/var/www/app/current/script/delayed_job -e production start"
    stop program = "/var/www/app/current/script/delayed_job -e production stop"

    Я сохраняю это в своей системе управления базой данных и указываю на него monit с помощью include /var/www/app/current/config/monit в файле /etc/monit/monitrc.

  4. Настроить monit. Эти инструкции содержат рекламу, но в остальном допустимы.
  5. Напишите задачу, чтобы капистрано остановилось и запустилось. monit start delayed_job и monit stop delayed_job - это то, что вы хотите запустить. Я также перезагружаю monit при развертывании, чтобы улавливать любые изменения файла конфигурации.

Проблемы, с которыми я столкнулся:

  1. Для работы script/delayed_job должен быть установлен гем daemons.
  2. Вы должны передать среду Rails в script/delayed_job с помощью -e production (например). Это задокументировано в файле README, но не в выводе справки скрипта.
  3. Я использую Ruby Enterprise Edition, поэтому мне нужно было получить monit, чтобы начать работу с этой копией Ruby. Из-за того, как sudo обрабатывает PATH в Ubuntu, мне пришлось создать символическую ссылку /usr/bin/ruby и /usr/bin/gem к версиям REE.

При отладке monit я обнаружил, что это помогает остановить версию init.d и запустить ее из командной строки th, чтобы вы могли получать сообщения об ошибках. В противном случае очень сложно понять, почему что-то идет не так.

sudo /etc/init.d/monit stop
sudo monit start delayed_job

Надеюсь, это поможет следующему человеку, который захочет контролировать delayed_job с помощью monit.

97
Community 23 Май 2017 в 12:16

Как бы то ни было, вы всегда можете использовать / usr / bin / env с monit для настройки среды. Это особенно важно в текущей версии delayed_job, 1.8.4, где параметр среды (-e) устарел.

check process delayed_job with pidfile /var/app/shared/pids/delayed_job.pid
start program = "/usr/bin/env RAILS_ENV=production /var/app/current/script/delayed_job start"
stop  program = "/usr/bin/env RAILS_ENV=production /var/app/current/script/delayed_job stop"

В некоторых случаях вам также может потребоваться установить PATH с помощью env.

8
mrchucho 12 Ноя 2009 в 14:55

Я обнаружил, что проще создать сценарий инициализации для отложенного задания. Он доступен здесь: http://gist.github.com/408929. или ниже:

#! /bin/sh
set_path="cd /home/rails/evatool_staging/current"

case "$1" in
  start)
        echo -n "Starting delayed_job: "
                su - rails -c "$set_path; RAILS_ENV=staging script/delayed_job start" >> /var/log/delayed_job.log 2>&1
        echo "done."
        ;;
  stop)
        echo -n "Stopping sphinx: "
                su - rails -c "$set_path; RAILS_ENV=staging script/delayed_job stop" >> /var/log/delayed_job.log 2>&1
        echo "done."
        ;;
      *)
            N=/etc/init.d/delayed_job_staging
            echo "Usage: $N {start|stop}" >&2
            exit 1
            ;;
    esac

    exit 0

Затем убедитесь, что monit настроен на запуск / перезапуск приложения, поэтому в вашем файле monitrc:

check process delayed_job with pidfile "/path_to_my_rails_app/shared/pids/delayed_job.pid"
start program = "/etc/init.d/delayed_job start"
stop program = "/etc/init.d/delayed_job stop"

И это прекрасно работает!

5
Jason Green 21 Май 2010 в 14:58

Я нашел хороший способ запустить delayed_job с помощью cron при загрузке. Я использую всякий раз для управления cron.

Мой schedule.rb:

# custom job type to control delayed_job
job_type :delayed_job, 'cd :path;RAILS_ENV=:environment script/delayed_job ":task"'

# delayed job start on boot
every :reboot do
  delayed_job "start"
end

Примечание: я обновлял каждый раз gem до версии 0.5.0, чтобы иметь возможность использовать job_type

5
Laurynas 30 Июн 2010 в 07:26

Не знаю, с Monit, но я написал пару плагинов Munin для отслеживания размера очереди. и Среднее время выполнения задания. Изменения, которые я внес в delayed_job в этом патче, также могут упростить вам написание плагинов Monit, если вы придерживаетесь этого.

2
agentofuser 4 Авг 2009 в 15:59

Спасибо за сценарий.

Одна проблема - поскольку monit по определению имеет 'спартанский путь' из

/bin:/usr/bin:/sbin:/usr/sbin

... и для меня рубин был установлен / связан в / usr / local / bin, мне пришлось часами ломать голову, пытаясь выяснить, почему monit молча терпел неудачу при попытке перезапустить delayed_job (даже с -v для режима подробного мониторинга) .

В итоге пришлось сделать вот что:

check process delayed_job with pidfile /var/www/app/shared/pids/delayed_job.pid
start program = "/usr/bin/env PATH=$PATH:/usr/local/bin /var/www/app/current/script/delayed_job -e production start"
stop program = "/usr/bin/env PATH=$PATH:/usr/local/bin /var/www/app/current/script/delayed_job -e production stop"
2
Julian H 5 Дек 2009 в 13:46

Мне пришлось объединить решения на этой странице с другим скриптом , созданный Тоби, чтобы он работал с monit и запускался с нужным пользователем.

Итак, мой delayed_job.monitrc выглядит так:

check process delayed_job
  with pidfile /var/app/shared/pids/delayed_job.pid
  start program = "/bin/su -c '/usr/bin/env RAILS_ENV=production /var/app/current/script/delayed_job start' - rails"
  stop program = "/bin/su -c '/usr/bin/env RAILS_ENV=production /var/app/current/script/delayed_job stop' - rails"
2
xiplias 28 Янв 2010 в 13:01

Если ваш монитор работает как root и вы хотите запустить delayed_job как my_user , сделайте следующее:

/etc/init.d/delayed_job :

#!/bin/sh
#   chmod 755 /etc/init.d/delayed_job
#   chown root:root /etc/init.d/delayed_job

case "$1" in
  start|stop|restart)
    DJ_CMD=$1
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit
esac

su -c "cd /var/www/my_app/current && /usr/bin/env bin/delayed_job $DJ_CMD" - my_user

/var/www/my_app/shared/monit/delayed_job.monitrc :

check process delayed_job with pidfile /var/www/my_app/shared/tmp/pids/delayed_job.pid
start program = "/etc/init.d/delayed_job start"
stop  program = "/etc/init.d/delayed_job stop"
if 5 restarts within 5 cycles then timeout

/ etc / monit / monitrc :

# add at bottom
include /var/www/my_app/shared/monit/*
2
Lev Lukomsky 30 Сен 2016 в 13:32

Поскольку я не хотел запускаться как root, я создал сценарий инициализации bash, который monit используется для запуска и остановки (PROGNAME будет абсолютным путем к script / delayed_job):

start() {
    echo "Starting $PROGNAME"
    sudo -u $USER /usr/bin/env HOME=$HOME RAILS_ENV=$RAILS_ENV $PROGNAME start
}

stop() {
    echo "Stopping $PROGNAME"
    sudo -u $USER /usr/bin/env HOME=$HOME RAILS_ENV=$RAILS_ENV $PROGNAME stop
}
1
Ben Marini 12 Ноя 2009 в 21:35

Я потратил довольно много времени на эту тему. Мне надоело не иметь для этого хорошего решения, поэтому я написал плагин delayed_job_tracer, который специально предназначен для мониторинга delayed_job и его заданий.

Вот статья, которую я написал об этом: http: // modernagility .com / article / 5-monitoring-delayed_job-and-its-jobs

Этот плагин будет отслеживать процесс отложенного задания и отправлять вам электронное письмо в случае сбоя delayed_job или сбоя одного из его заданий.

1
Kenny Johnston 26 Май 2010 в 22:32

Для Rails 3 вам может потребоваться установить HOME env, чтобы компас работал правильно, и у меня работает конфигурация ниже:

check process delayed_job
  with pidfile /home/user/app/shared/pids/delayed_job.pid
  start program = "/bin/sh -c 'cd /home/user/app/current; HOME=/home/user RAILS_ENV=production script/delayed_job start'"
  stop program  = "/bin/sh -c 'cd /home/user/app/current; HOME=/home/user RAILS_ENV=production script/delayed_job stop'"
1
yuanyiz1 16 Авг 2011 в 04:03

Я столкнулся с проблемой, из-за которой, если отложенное задание умирает, пока оно все еще заблокировано, это задание не будет освобождено. Я написал сценарий-оболочку для отложенного задания, который просматривает файл pid и освобождает все задания от мертвого рабочего.

Скрипт для резины / капистрано

Роли / delayedjob / delayed_job_wrapper:

<% @path = '/etc/monit/monit.d/monit-delayedjob.conf' %>
<% workers = 4 %>
<% workers.times do |i| %>
<% PIDFILE = "/mnt/custora-#{RUBBER_ENV}/shared/pids/delayed_job.#{i}.pid" %>
<%= "check process delayed_job.#{i} with pidfile #{PIDFILE}"%>
group delayed_job-<%= RUBBER_ENV %>
<%= " start program = \"/bin/bash /mnt/#{rubber_env.app_name}-#{RUBBER_ENV}/current/script/delayed_job_wrapper #{i} start\"" %>
<%= " stop program = \"/bin/bash /mnt/#{rubber_env.app_name}-#{RUBBER_ENV}/current/script/delayed_job_wrapper #{i} stop\"" %>
<% end %>

Роли / отложенная работа / delayed_job_wrapper

#!/bin/bash
<%   @path = "/mnt/#{rubber_env.app_name}-#{RUBBER_ENV}/current/script/delayed_job_wrapper" %>

<%= "pid_file=/mnt/#{rubber_env.app_name}-#{RUBBER_ENV}/shared/pids/delayed_job.$1.pid" %>
if [ -e $pid_file ]; then
 pid=`cat $pid_file`
 if [ $2 == "start" ]; then
   ps -e | grep ^$pid
   if [ $? -eq 0 ]; then
     echo "already running $pid"
     exit
   fi
   rm $pid_file
 fi

locked_by="delayed_job.$1 host:`hostname` pid:$pid"

<%="   /usr/bin/mysql -e \"update delayed_jobs set locked_at = null, locked_by = null where locked_by='$locked_by'\" -u#{rubber_env.db_user} -h#{rubber_instances.for_role('db', 'primary' => true).first.full_name}  #{rubber_env.db_name} " %>

fi
<%= "cd /mnt/#{rubber_env.app_name}-#{RUBBER_ENV}/current" %>

. /etc/profile
<%= "RAILS_ENV=#{RUBBER_ENV} script/delayed_job -i $1 $2"%>
0
aaronjg 31 Янв 2012 в 03:06

Чтобы увидеть, что происходит, запустите monit в подробном режиме переднего плана: sudo monit -Iv

С помощью rvm, установленного пользователем "www1" и группой "www1".

В файле /etc/monit/monitrc:

#delayed_job
check process delayed_job with pidfile /home/www1/your_app/current/tmp/pids/delayed_job.pid
    start program "/bin/bash -c 'PATH=$PATH:/home/www1/.rvm/bin;source /home/www1/.rvm/scripts/rvm;cd /home/www1/your_app/current;RAILS_ENV=production bundle exec script/delayed_job start'" as uid www1 and gid www1
    stop program "/bin/bash -c 'PATH=$PATH:/home/www1/.rvm/bin;source /home/www1/.rvm/scripts/rvm;cd /home/www1/your_app/current;RAILS_ENV=production bundle exec script/delayed_job stop'" as uid www1 and gid www1
    if totalmem is greater than 200 MB for 2 cycles then alert
0
manitu 11 Янв 2015 в 20:39