Pregunta

¿Hay ejemplos en la web de cómo monitorear delayed_job con Monit ?

Todo lo que puedo encontrar usa Dios , pero me niego a usar a Dios, ya que los procesos de larga ejecución en Ruby generalmente apestan . (¿La publicación más reciente en la lista de correo de Dios? El uso de la memoria de Dios crece constantemente .)

Actualización: delayed_job ahora viene con un muestra de configuración de monit basada en esta pregunta.

¿Fue útil?

Solución

Así es como lo hice funcionar.

  1. Use el collectiveidea fork of delayed_job además de mantenerse activamente, esta versión tiene un buen script / delayed_job daemon que puedes usar con monit. Railscasts tiene un buen episodio sobre esta versión de delayed_job ( versión ASCIICasts ). Este script también tiene algunas otras características interesantes, como la capacidad de ejecutar varios trabajadores. No cubro eso aquí.
  2. Instalar monit. Lo instalé desde el origen porque la versión de Ubuntu está ridículamente desactualizada. Seguí estas instrucciones para obtener el scripts init.d estándar que vienen con los paquetes de Ubuntu. También necesitaba configurar con ./configure --sysconfdir = / etc / monit para que se recogiera el directorio de configuración estándar de Ubuntu.
  3. Escribe un script monit. Esto es lo que se me ocurrió:

    proceso de verificación delayed_job con pidfile /var/www/app/shared/pids/delayed_job.pid
    start program = " / var / www / app / current / script / delayed_job -e start product "
    stop program = " / var / www / app / current / script / delayed_job -e production stop "

    Almaceno esto en mi sistema de control soucre y apunto a monit con include / var / www / app / current / config / monit en / etc / monit / monitrc archivo.

  4. Configurar monit. Estas instrucciones están cargadas de anuncios pero, por lo demás, están bien.
  5. Escribe una tarea para que capistrano se detenga y comience. monit start delayed_job y monit stop delayed_job es lo que desea ejecutar. También recargo monit al implementar para recoger cualquier cambio en el archivo de configuración.

Problemas que encontré:

    La gema
  1. daemons debe estar instalada para que se ejecute script / delayed_job .
  2. Debe pasar el entorno Rails a script / delayed_job con -e production (por ejemplo). Esto está documentado en el archivo README pero no en la salida de ayuda del script.
  3. Uso Ruby Enterprise Edition, así que necesitaba obtener monit para comenzar con esa copia de Ruby. Debido a la forma en que sudo maneja la RUTA en Ubuntu, terminé simpatizando / usr / bin / ruby ?? y / usr / bin / gem a las versiones REE.

Al depurar monit, descubrí que ayuda a detener la versión init.d y ejecutarla desde la línea de comando th, para que pueda obtener mensajes de error. De lo contrario, es muy difícil descubrir por qué las cosas van mal.

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

Espero que esto ayude a la próxima persona que quiera monitorear delayed_job con monit.

Otros consejos

Para lo que vale, siempre puede usar / usr / bin / env con monit para configurar el entorno. Esto es especialmente importante en la versión actual de delayed_job, 1.8.4, donde la opción de entorno (-e) está en desuso.

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"

En algunos casos, es posible que también necesite configurar la RUTA con env.

Descubrí que era más fácil crear un script de inicio para el trabajo retrasado. Está disponible aquí: http://gist.github.com/408929 o debajo:

#! /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

Luego, asegúrese de que monit esté configurado para iniciar / reiniciar la aplicación, así que en su archivo 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"

¡y eso funciona muy bien!

Encontré una buena manera de iniciar delayed_job con cron en el arranque. Estoy usando siempre que para controlar el cron.

Mi horario.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

Nota: Actualicé cada vez que gem a la versión 0.5.0 para poder usar job_type

No lo sé con Monit, pero he escrito un par de complementos Munin para supervisar el tamaño de la cola y el tiempo promedio de ejecución del trabajo. Los cambios que hice en delayed_job en ese parche también podrían facilitarle la escritura de complementos de Monit en caso de que se quede con eso.

Gracias por el guión.

Un problema: dado que monit, por definición, tiene una 'ruta espartana' de

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

... y para mí Ruby estaba instalado / vinculado en / usr / local / bin, tuve que dar vueltas durante horas tratando de averiguar por qué monit fallaba silenciosamente al intentar reiniciar el trabajo retrasado (incluso con -v para monit modo detallado).

Al final tuve que hacer esto:

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"

Tuve que combinar las soluciones en esta página con otra script creado por toby para que funcione con monit y comience con el usuario correcto.

Entonces mi delayed_job.monitrc se ve así:

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"

Si su monitor se está ejecutando como root y desea ejecutar delayed_job como my_user , haga esto:

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

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

/ etc / monit / monitrc :

<*>

Como no quería ejecutarme como root, terminé creando un script bash init que monit usaba para iniciar y detener (PROGNAME sería la ruta absoluta al 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
}

He dedicado bastante tiempo a este tema. Estaba harto de no tener una buena solución, así que escribí el plugin delayed_job_tracer que aborda específicamente el monitoreo de delayed_job y sus trabajos.

Aquí hay un artículo que he escrito al respecto: http: //modernagility.com/articles/5-monitoring-delayed_job-and-its-jobs

Este complemento supervisará su proceso de trabajo retrasado y le enviará un correo electrónico si delayed_job falla o si falla uno de sus trabajos.

Para Rails 3, es posible que necesite configurar HOME env para que la brújula funcione correctamente, y la siguiente configuración me funciona:

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

Me encontré con un problema en el que si el trabajo retrasado muere mientras todavía tiene un trabajo bloqueado, ese trabajo no se liberará. Escribí un script de envoltura sobre el trabajo retrasado que examinará el archivo pid y liberará cualquier trabajo del trabajador muerto.

El script es para rubber / capistrano

roles / 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 %>

roles / 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"%>

para ver lo que está sucediendo, ejecute monit en modo detallado en primer plano: sudo monit -Iv

usando rvm instalado bajo el usuario " www1 " y grupo " www1 " ;.

en el archivo / 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top