12 votes

delayed_job s'arrête de fonctionner après un certain temps en production

En production, notre delayed_job est en train de mourir pour une raison ou une autre. Je ne sais pas s'il se bloque ou s'il est tué par le système d'exploitation ou quoi. Je ne vois aucune erreur dans le delayed_job.log fichier.

Que puis-je faire pour résoudre ce problème ? Je pensais installer surveiller pour le surveiller, mais cela ne m'indiquera que le moment précis où il mourra. Cela ne me dira pas vraiment pourquoi il est mort.

Existe-t-il un moyen de le rendre plus bavard dans le fichier journal, afin que je puisse savoir pourquoi il est en train de mourir ?

D'autres suggestions ?

12voto

Luke Chadwick Points 1172

J'ai rencontré deux causes pour lesquelles delayed_job échoue silencieusement. La première est la présence de segfaults lorsque des personnes utilisaient libxml dans des processus forkés (ceci est apparu sur la liste de diffusion il y a quelque temps).

Le second est un problème lié à la version 1.1.0 des démons sur lesquels s'appuie delayed_job ( https://github.com/collectiveidea/delayed_job/issues#issue/81 ), ceci peut être facilement contourné en utilisant la version 1.0.10 qui est celle de mon propre fichier Gemfile.

Enregistrement

Il y a une journalisation dans delayed_job, donc si le travailleur meurt sans afficher d'erreur, c'est généralement parce qu'il ne lance pas d'exception (par exemple Segfault) ou parce que quelque chose d'externe tue le processus.

Contrôle

J'utilise bluepill pour surveiller mes instances de tâches retardées, et jusqu'à présent cela a été très efficace pour s'assurer que les tâches restent en cours d'exécution. Les étapes pour faire fonctionner bluepill pour une application sont assez simples

Ajoutez la gem bluepill à votre Gemfile :

 # Monitoring
  gem 'i18n' # Not sure why but it complained I didn't have it
  gem 'bluepill'

J'ai créé un fichier de configuration bluepill :

app_home = "/home/mi/production"
workers = 5
Bluepill.application("mi_delayed_job", :log_file => "#{app_home}/shared/log/bluepill.log") do |app|
  (0...workers).each do |i|
    app.process("delayed_job.#{i}") do |process|
      process.working_dir = "#{app_home}/current"

      process.start_grace_time    = 10.seconds
      process.stop_grace_time     = 10.seconds
      process.restart_grace_time  = 10.seconds

      process.start_command = "cd #{app_home}/current && RAILS_ENV=production ruby script/delayed_job start -i #{i}"
      process.stop_command  = "cd #{app_home}/current && RAILS_ENV=production ruby script/delayed_job stop -i #{i}"

      process.pid_file = "#{app_home}/shared/pids/delayed_job.#{i}.pid"
      process.uid = "mi"
      process.gid = "mi"
    end
  end
end

Ensuite, dans mon fichier de déploiement capistrano, j'ai juste ajouté :

# Bluepill related tasks
after "deploy:update", "bluepill:quit", "bluepill:start"
namespace :bluepill do
  desc "Stop processes that bluepill is monitoring and quit bluepill"
  task :quit, :roles => [:app] do
    run "cd #{current_path} && bundle exec bluepill --no-privileged stop"
    run "cd #{current_path} && bundle exec bluepill --no-privileged quit"
  end

  desc "Load bluepill configuration and start it"
  task :start, :roles => [:app] do
    run "cd #{current_path} && bundle exec bluepill --no-privileged load /home/mi/production/current/config/delayed_job.bluepill"
  end

  desc "Prints bluepills monitored processes statuses"
  task :status, :roles => [:app] do
    run "cd #{current_path} && bundle exec bluepill --no-privileged status"
  end
end

J'espère que cela vous aidera un peu.

2voto

Siwei Shen Points 5814

Le cas le plus courant que j'ai rencontré pour ce problème est causé par des problèmes de base de données (erreurs de connexion mysql ou autres). Il n'y a pas de logs par défaut.

Je vous suggère donc d'utiliser dieu pour contrôler votre delayed_job ( vous pouvez voir son fichier log ! ) .

si vous utilisez delayed_job avec Rails4, vous devriez le faire :

1.installer la gemme god : $gem install god

2. avoir ce fichier script :

# filename: cache_cleaner.god
RAILS_ROOT = '/sg552/workspace/m-api-cache-cleaner'
God.watch do |w| 
  w.name = 'cache_cleaner'
  w.dir = RAILS_ROOT
  w.start = "cd #{RAILS_ROOT} && RAILS_ENV=production bundle exec bin/delayed_job -n 5 start"
  w.stop = "cd #{RAILS_ROOT} && RAILS_ENV=production bundle exec bin/delayed_job stop"
  w.restart = "cd #{RAILS_ROOT} && RAILS_ENV=production bundle exec bin/delayed_job -n 5 restart"
  w.log = "#{RAILS_ROOT}/log/cache_cleaner_stdout.log"
  w.pid_file = File.join(RAILS_ROOT, "log/delayed_job.total.pid")
  # you should NEVER use this config settings: 
  # w.keepalive   (always comment it out! ) 
end

3. pour démarrer/arrêter/redémarrer delayed_jobs, changez votre commande de :

$ bundle exec bin/delayed_job -n 3 start

à :

$ god -c cache_cleaner.god -D  
$ god start/stop/restart cache_cleaner

se référer à mon blog personnel : http://siwei.me/blog/posts/using-delayed-job-with-god

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X