如何使用 monit 监控延迟作业

网络上有没有关于如何使用 Monit监控延迟作业的例子?

我能找到的所有东西都使用 天啊,但我拒绝使用 God,因为在 Ruby 中长时间运行的进程通常很糟糕。(上帝邮件列表中最新的帖子?上帝记忆的使用稳步增长)

更新: 基于这个问题,现在延迟作业附带了一个 样本 monit 配置样本 monit 配置

34176 次浏览

我不知道如何使用 Monit,但是我已经编写了一个 几个 Munin 插件来监视队列大小和平均作业运行时间。我对那个补丁中的  作業延迟所做的更改也會讓您更容易地寫出 Monit 插件,以防您一直沿用那個方法。

我是这么做的。

  1. 除了主动维护之外,使用 延迟作业的分支,这个版本还有一个不错的 script/delayed_job守护进程,可以用于 monit。Railcast 有关于这个版本的 delayed_job(ASCIICast 版本)的 精彩的一集。这个脚本还有其他一些很好的特性,比如运行多个 worker 的能力。我在这里不谈这个。
  2. 安装 Monit。我从源代码安装是因为 Ubuntu 的版本过时得离谱。我跟随 这些指示获得了 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" < br/>

    我把它存储在我的源代码控制系统中,然后用 /etc/monit/monitrc文件中的 include /var/www/app/current/config/monit对它进行点监视。

  4. 配置 monit。 这些说明充满了广告,但其他方面没问题。
  5. 写一个任务让 Capistrano 停下来开始。要运行的是 monit start delayed_jobmonit stop delayed_job。我还在部署时重新加载 monit,以获取任何配置文件更改。

我遇到的问题:

  1. 必须安装 daemons gem 才能运行 script/delayed_job
  2. 您必须使用 -e production将 Rails 环境传递给 script/delayed_job(例如)。这在 README 文件中有文档说明,但在脚本的帮助输出中没有。
  3. 我使用 Ruby 企业版,所以我需要让 monit 从 Ruby 的那个副本开始。由于 Ubuntu 中 Sudo 处理 PATH的方式,我最终将 /usr/bin/ruby/usr/bin/gem符号连接到 REE 版本。

在调试 monit 时,我发现停止 init.d 版本并从 th 命令行运行它会有所帮助,因此您可以得到错误消息。否则就很难弄清楚事情为什么会出错。

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

希望这能帮助下一个想用 monit 监视 delayed_job的人。

不管怎样,您总是可以使用/usr/bin/env 和 monit 来设置环境。这一点在当前版本的  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。

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

谢谢你的剧本。

一个问题是——因为根据定义,monit 的 “斯巴达小径”

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

对于我来说,Ruby 被安装/链接到/usr/local/bin 中,我不得不绞尽脑汁花上几个小时,试图弄清楚为什么在尝试重新启动延迟 _ job 时,monit 无声无息地失败了(即使是在-v 模式下,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"

我必须结合这个网页上的解决方案与另一个 剧本的托比,使其工作与莫尼特,并从正确的用户开始。

所以我的延迟工作. monitor 看起来像这样:

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"

我发现为延迟作业创建 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 设置为启动/重新启动应用程序,这样就可以在 montrc 文件中显示:

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"

效果很好!

我在这个话题上花了不少时间。我已经厌倦了没有一个好的解决方案,所以我编写了延迟 _ job _ tracer 插件,专门处理延迟 _ job 及其作业的监视。

这是我写的一篇关于它的文章: http://modernagility.com/articles/5-monitoring-delayed_job-and-its-jobs

这个插件将监视您的延迟作业过程,并且如果  延迟作业崩溃或者其中一個作业失败,就會向您发送一封 email。

我找到了一种在引导时启动 cron 的延迟 _ job 的好方法,我正在使用 无论何时来控制 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

注意: 为了能够使用 job _ type,我每次都将 gem 升级到0.5.0版本

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

我遇到了一个问题,如果延迟的作业死亡,而它仍然有一个作业被锁定,该作业将不会被释放。我针对延迟作业编写了一个包装器脚本,该脚本将查看 pid 文件并从死亡工人中释放任何作业。

该脚本是橡胶/Capistrano

Role/delayedjob/ 堵 _ 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 %>

Role/delayedjob/宫位/延迟 _ 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"%>

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

使用安装在用户“ www1”和组“ www1”下的 rvm

档案 /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

如果 monit 以 的形式运行,并且您想以 My _ user的形式运行 late _ job,那么可以这样做:

/etc/init.d/late _ 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/share/monit/late _ job. monitor rc :

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/monitor :

# add at bottom
include /var/www/my_app/shared/monit/*