如何用monit监视delayed_job

时间:2009-08-04 08:30:23

标签: ruby-on-rails ruby delayed-job monit god

网上是否有关于如何使用Monit监控delayed_job的示例?

我能找到的所有内容都使用God,但我拒绝使用上帝,因为Ruby中长时间运行的过程通常很糟糕。 (上帝邮件列表中最新的帖子?God Memory Usage Grows Steadily。)

更新: delayed_job现在根据此问题提供sample monit config

13 个答案:

答案 0 :(得分:97)

以下是我的工作方式。

  1. 除了积极维护之外,使用collectiveidea fork of delayed_job,此版本还有一个可以与monit一起使用的好script/delayed_job守护进程。 Railscasts对此版本的delayed_joba good episode)有ASCIICasts version。此脚本还具有一些其他不错的功能,例如运行多个工作程序的功能。我不在此处讨论。
  2. 安装monit。我从源码安装,因为Ubuntu的版本是如此荒谬的过时。我按照these instructions获取了Ubuntu软件包附带的标准init.d脚本。我还需要配置./configure --sysconfdir=/etc/monit,以便选择标准的Ubuntu配置目录。
  3. 编写一个monit脚本。这就是我想出的:

    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"

    我将它存储在我的soucre控制系统中,并使用include /var/www/app/current/config/monit文件中的/etc/monit/monitrc指向monit。

  4. 配置monit。 These instructions载有广告但其他方式还可以。
  5. 为capistrano写一个任务来停止并开始。 monit start delayed_jobmonit stop delayed_job是你想要运行的。我还在部署以获取任何配置文件更改时重新加载monit。
  6. 我遇到的问题:

      必须安装
    1. daemons gem才能运行script/delayed_job
    2. 您必须使用script/delayed_job将Rails环境传递给-e production(例如)。这在README文件中有记录,但在脚本的帮助输出中没有记录。
    3. 我使用Ruby Enterprise Edition,所以我需要monit从Ruby的副本开始。由于Ubuntu中sudo handles the PATH的方式,我最终将/usr/bin/ruby/usr/bin/gem符号链接到REE版本。
    4. 调试monit时,我发现停止init.d版本并从命令行运行它有帮助,这样你就可以收到错误消息。否则,很难弄清楚出现问题的原因。

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

      希望这有助于下一个想要监控delayed_job monit的人。

答案 1 :(得分:8)

对于它的价值,你总是可以使用/ 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"

在某些情况下,您可能还需要使用env设置PATH。

答案 2 :(得分:5)

我发现为延迟作业创建init脚本更容易。它可以在这里找到: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"

这很有效!

答案 3 :(得分:5)

我发现在启动时使用cron启动delayed_job的好方法。我正在使用whenever来控制cron。

我的日程表.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

答案 4 :(得分:2)

我不认识Monit,但我写了一个couple Munin plugins来监控队列大小和平均作业运行时间。我对该补丁中对delayed_job所做的更改也可能使您更容易编写Monit插件,以防您坚持使用。

答案 5 :(得分:2)

感谢您的脚本。

一个问题 - 因为monit的定义是'spartan path'

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

...对我来说,在/ usr / local / bin中安装/链接了ruby,我不得不捣乱几个小时试图弄清楚为什么monit在尝试重新启动delayed_job时默默地失败(即使使用-v for monit详细模式)。

最后我必须这样做:

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"

答案 6 :(得分:2)

我必须将此页面上的解决方案与toby制作的另一个script结合起来,使其与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"

答案 7 :(得分:2)

如果您的monit以 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/*

答案 8 :(得分:1)

由于我不想以root身份运行,我最终创建了一个bash init脚本,monit用于启动和停止(PROGNAME将是脚本/ 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
}

答案 9 :(得分:1)

我花了很多时间讨论这个话题。我厌倦了没有一个好的解决方案,所以我编写了delayed_job_tracer插件,专门用于监控delayed_job及其工作。

以下是我撰写的一篇文章:http://modernagility.com/articles/5-monitoring-delayed_job-and-its-jobs

如果delayed_job崩溃或其中一个作业失败,此插件将监控您的延迟作业流程并向您发送电子邮件。

答案 10 :(得分:1)

对于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'"

答案 11 :(得分:0)

我遇到了一个问题,如果延迟的作业在仍然锁定作业时死亡,那么该作业将不会被释放。我写了一个关于延迟作业的包装脚本,它将查看pid文件并释放死亡工作者的所有工作。

该脚本适用于rubber / capistrano

角色/ 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 %>

角色/ delayedjob / 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"%>

答案 12 :(得分:0)

要查看发生了什么,请在前台详细模式下运行monit:sudo monit -Iv

使用用户&#34; www1&#34;下安装的rvm和小组&#34; www1&#34;。

文件/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