web-dev-qa-db-fra.com

Comment surveiller le travail différé avec Monit

Existe-t-il des exemples sur le Web de la façon de surveiller le travail différé avec Monit ?

Tout ce que je peux trouver utilise Die , mais je refuse d'utiliser Dieu car les processus longs en Ruby sont généralement nulles. (Le message le plus récent dans la liste de diffusion de Dieu? - L'utilisation de la mémoire de Dieu augmente régulièrement .)

Mise à jour: delay_job est maintenant livré avec un exemple de configuration de monit basé sur cette question.

74
Luke Francl

Voici comment je l'ai fait fonctionner.

  1. Utilisez la fourche collectiveidea de delay_job en plus d'être activement maintenue, cette version a une belle script/delayed_job démon que vous pouvez utiliser avec monit. Railscasts a n bon épisode à propos de cette version de delayed_job ( version ASCIICasts ). Ce script a également d'autres fonctionnalités intéressantes, comme la possibilité d'exécuter plusieurs travailleurs. Je ne couvre pas cela ici.
  2. Installez monit. J'ai installé à partir des sources parce que la version d'Ubuntu est ridiculement obsolète. J'ai suivi ces instructions pour obtenir les scripts init.d standard fournis avec les packages Ubuntu. J'ai également dû configurer avec ./configure --sysconfdir=/etc/monit donc le répertoire de configuration standard d'Ubuntu a été récupéré.
  3. Écrivez un script monit. Voici ce que j'ai trouvé:

    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"

    Je le stocke dans mon système de contrôle de soucre et je le pointe avec include /var/www/app/current/config/monit dans le /etc/monit/monitrc fichier.

  4. Configurez monit. Ces instructions sont chargées de publicités mais sinon OK.
  5. Écrivez une tâche pour que capistrano s'arrête et démarre. monit start delayed_job et monit stop delayed_job est ce que vous voulez exécuter. Je recharge également monit lors du déploiement pour récupérer les modifications du fichier de configuration.

Problèmes que j'ai rencontrés:

  1. daemons gem doit être installé pour script/delayed_job courir.
  2. Vous devez transmettre l'environnement Rails à script/delayed_job avec -e production (par exemple). Ceci est documenté dans le fichier README mais pas dans la sortie d'aide du script.
  3. J'utilise Ruby Enterprise Edition, donc je devais obtenir monit pour commencer avec cette copie de Ruby. En raison de la manière Sudo gère le CHEMIN dans Ubuntu, j'ai fini par lien symbolique /usr/bin/Ruby et /usr/bin/gem aux versions REE.

Lors du débogage de monit, j'ai trouvé qu'il était utile d'arrêter la version init.d et de l'exécuter à partir de la ligne de commande, afin que vous puissiez obtenir des messages d'erreur. Sinon, il est très difficile de comprendre pourquoi les choses tournent mal.

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

Espérons que cela aide la prochaine personne qui souhaite surveiller delayed_job avec monit.

97
Luke Francl

Pour ce que ça vaut, vous pouvez toujours utiliser/usr/bin/env avec monit pour configurer l'environnement. Ceci est particulièrement important dans la version actuelle de delay_job, 1.8.4, où l'option d'environnement (-e) est déconseillé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"

Dans certains cas, vous devrez peut-être également définir le PATH avec env.

8
mrchucho

J'ai trouvé qu'il était plus facile de créer un script d'initialisation pour un travail retardé. Il est disponible ici: http://Gist.github.com/408929 ou ci-dessous:

 #! /bin/sh[.____.[set_path="cd /home/Rails/evatool_staging/current"}.____. -n "Démarrage du travail différé:" 
 su - Rails -c "$ set_path; Rails_ENV = script intermédiaire/démarrage du travail différé" >> /var/log/delayed_job.log 2> & 1 
 Echo "terminé." 
 ;; 
 Arrêt) 
 Echo -n "Arrêt du sphinx:" 
 Su - Rails -c "$ set_path; Rails_ENV = script intermédiaire/arrêt de travail différé" >> /var/log/delayed_job.log 2> & 1 
 Echo "done." 
 ;; 
 *) 
 N =/etc/init.d/delay_job_staging 
 Echo "Utilisation: $ N {start | stop}"> & 2 
 Exit 1 
 ;; 
 esac 
 
 exit 0 

Assurez-vous ensuite que monit est configuré pour démarrer/redémarrer l'application dans votre fichier monitrc:

vérifier le processus delay_job avec le fichier pid "/path_to_my_Rails_app/shared/pids/delayed_job.pid"}.____. d/arrêt du travail différé "

et ça marche super!

5
Jason Green

J'ai trouvé un bon moyen de démarrer le travail différé avec cron au démarrage. J'utilise à chaque fois pour contrôler cron.

Mon horaire.rb:

 # type de travail personnalisé pour contrôler le travail différé 
 type_travail: travail retardé, 'cd: chemin; Rails_ENV =: script d'environnement/travail_diffusé ": tâche"' 
 
 # retardé début du travail au démarrage 
 tous les: redémarrage faire 
 travail_dardé "démarrer" 
 fin 

Remarque: J'ai mis à niveau chaque fois que gem vers la version 0.5.0 pour pouvoir utiliser job_type

5
Laurynas

Merci pour le script.

Un gotcha - puisque monit par définition a un 'chemin spartiate' de

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

... et pour moi Ruby a été installé/lié dans/usr/local/bin, j'ai dû me débattre pendant des heures en essayant de comprendre pourquoi monit échouait silencieusement en essayant de redémarrer delay_job ( même avec -v pour le mode verbeux monit).

Au final, j'ai dû faire ceci:

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

Si votre monit s'exécute en tant que root ​​et que vous souhaitez exécuter delay_job en tant que my_user, procédez comme suit:

/etc/init.d/delay_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/delay_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

J'ai dû combiner les solutions de cette page avec une autre script faite par toby pour la faire fonctionner avec monit et en commençant par le bon utilisateur.

Donc, mon différé_job.monitrc ressemble à ceci:

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

Je ne sais pas avec Monit, mais j'ai écrit un quelques plugins Munin pour surveiller la taille de la file d'attente et le temps d'exécution moyen des travaux. Les modifications que j'ai apportées à delay_job dans ce patch pourraient également vous faciliter l'écriture de plugins Monit au cas où vous vous en tiendriez à cela.

2
hsribei

Comme je ne voulais pas exécuter en tant que root, j'ai fini par créer un script d'initialisation bash qui serait utilisé pour démarrer et arrêter (PROGNAME serait le chemin absolu vers script/delay_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

J'ai passé pas mal de temps sur ce sujet. J'en avais marre de ne pas avoir de bonne solution, j'ai donc écrit le plugin delay_job_tracer qui traite spécifiquement de la surveillance de delay_job et de ses jobs.

Voici un article que j'ai écrit à ce sujet: http://modernagility.com/articles/5-monitoring-delayed_job-and-its-jobs

Ce plugin surveillera votre processus de travail retardé et vous enverra un e-mail en cas de plantage de delay_job ou si l'un de ses travaux échoue.

1
Kenny Johnston

Pour Rails 3, vous devrez peut-être définir HOME env pour que la boussole fonctionne correctement, et la configuration ci-dessous fonctionne pour moi:

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

pour voir ce qui se passe, exécutez monit en mode détaillé au premier plan: Sudo monit -Iv

en utilisant rvm installé sous l'utilisateur "www1" et le groupe "www1".

dans le fichier /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
kitschmaster

J'ai rencontré un problème où si le travail retardé meurt alors qu'il a toujours un travail verrouillé, ce travail ne sera pas libéré. J'ai écrit un script wrapper autour du travail retardé qui examinera le fichier pid et libérera tous les travaux du travailleur mort.

Le script est pour le caoutchouc/capistrano

rôles/emploi retardé/emploi_dossier_tardé:

<% @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 %>

rôles/emploi retardé/emploi_dossier_dardé

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