Запустите resque в фоновом режиме - PullRequest
22 голосов
/ 13 ноября 2011

У меня есть рабочее приложение rails с системой очередей Resque, которая работает очень хорошо. Тем не менее, мне не хватает хорошего способа на самом деле демонизировать работников resque.

Я могу запустить их просто отлично, выполнив rake resque: work QUEUE = "*", но, думаю, дело не в том, чтобы ваши работники работали на переднем плане. По какой-то причине никто, похоже, не занимается этим вопросом. На официальной странице Resque GitHub вы можете сделать что-то вроде этого:

PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work

хорошо - здесь, по крайней мере, он не разваливается на задний план.

Ответы [ 8 ]

15 голосов
/ 27 января 2012

+1 для Resque-Pool - это действительно круто.Мы используем его в сочетании с Богом, чтобы убедиться, что он всегда доступен.

# Resque
God.watch do |w|

  w.dir = RAILS_ROOT

  w.name = "resque-pool"
  w.interval = 30.seconds
  w.start = "cd #{RAILS_ROOT} && sudo -u www-data sh -c 'umask 002 && resque-pool -d -E #{RAILS_ENV}'"
  w.start_grace = 20.seconds
  w.pid_file = "#{RAILS_ROOT}/tmp/pids/resque-pool.pid"

  w.behavior(:clean_pid_file)

  # restart if memory gets too high
  #w.transition(:up, :restart) do |on|
  #  on.condition(:memory_usage) do |c|
  #    c.above = 350.megabytes
  #    c.times = 2
  #  end
  #end

  # determine the state on startup
  w.transition(:init, { true => :up, false => :start }) do |on|
    on.condition(:process_running) do |c|
      c.running = true
    end
  end

  # determine when process has finished starting
  w.transition([:start, :restart], :up) do |on|
    on.condition(:process_running) do |c|
      c.running = true
      c.interval = 5.seconds
    end

    # failsafe
    on.condition(:tries) do |c|
      c.times = 5
      c.transition = :start
      c.interval = 5.seconds
    end
  end

  # start if process is not running
  w.transition(:up, :start) do |on|
    on.condition(:process_running) do |c|
      c.running = false
    end
  end
end

Это дает вам действительно элегантный способ перезагрузить код в ваших работниках, не прерывая работу - просто kill -2 ваше восстановлениепул (ы) при развертывании.Бесполезные работники немедленно умрут, занятые работники умрут, когда они закончат свою текущую работу, и Бог перезапустит ресвек-пул с работниками, использующими ваш новый код.

Это наши задачи Resque для Capistrano:

namespace :resque do

  desc "Starts resque-pool daemon."
  task :start, :roles => :app, :only => { :jobs => true } do
    run "cd #{current_path};resque_pool -d -e #{rails_env} start"
  end

  desc "Sends INT to resque-pool daemon to close master, letting workers finish their jobs."
  task :stop, :roles => :app, :only => { :jobs => true } do
    pid = "#{current_path}/tmp/pids/resque-pool.pid"
    sudo "kill -2 `cat #{pid}`"
  end

  desc "Restart resque workers - actually uses resque.stop and lets God restart in due course."
  task :restart, :roles => :app, :only => { :jobs => true } do
    stop # let God restart.
  end

  desc "List all resque processes."
  task :ps, :roles => :app, :only => { :jobs => true } do
    run 'ps -ef f | grep -E "[r]esque-(pool|[0-9])"'
  end

  desc "List all resque pool processes."
  task :psm, :roles => :app, :only => { :jobs => true } do
    run 'ps -ef f | grep -E "[r]esque-pool"'
  end

end

Возможно, вам понадобится переподключить любые соединения с БД, когда работники вилок resque-pool - проверьте документы.

13 голосов
/ 10 января 2012

У меня была такая же проблема, и у меня работает следующее.

PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work >>  worker1.log &

Вы также можете перенаправить STDERR в тот же файл журнала.

5 голосов
/ 14 ноября 2011

Чтобы демонизировать процесс, вы можете использовать nohup :

nohup cmd &

В Resque github есть конфигурация для monit, которая показывает, как использовать nohupэто выглядит примерно так:

nohup bundle exec rake resque:work QUEUE=queue_name PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1
4 голосов
/ 22 января 2012

Другой вариант, на который вам следует обратить внимание, - это использование resque pool gem для управления вашими работниками.

Вы можете запустить Resque Pool в фоновом режиме, используя эту команду:

resque-pool --daemon - окружающая среда производства

2 голосов
/ 28 февраля 2012

Переменная среды BACKGROUND была добавлена ​​в Resque 1.20;убедитесь, что вы не используете 1.19 или ниже.

1 голос
/ 30 мая 2014

Я также сталкивался с этой проблемой, я запускаю работника в задаче cap, но у меня возникла проблема

  • ФОН заставляет работника всегда находиться в режиме запуска.
  • Процесс nohup завершается сразу после завершения, мы должны подождать пару секунд.Но не в состоянии добавить больше команд после '&'

Наконец, я должен создать оболочку, пусть она спит 5 секунд после вызова nohup ....Мой код

desc 'Start resque'
task :start, :roles => :app do
  run("cd #{current_path} ; echo \"nohup bundle exec rake resque:work QUEUE=* RAILS_ENV=#{rails_env} PIDFILE=tmp/pids/resque_worker_1.pid &\nnohup bundle exec rake resque:work QUEUE=* RAILS_ENV=#{rails_env} PIDFILE=tmp/pids/resque_worker_2.pid &\nsleep 5s\" > startworker.sh ")
  run("cd #{current_path} ; chmod +x startworker.sh")
  run("cd #{current_path} ; ./startworker.sh")
  run("cd #{current_path} ; rm startworker.sh")
end

Я знаю, что это решение ситуации.но это хорошо работает в моем проекте

1 голос
/ 24 января 2012

Один хороший способ - использовать Бога для управления им. Он запускает демонизированную версию Resque и следит за ней. На самом деле, вы можете выбрать между использованием Resque в качестве демона и позволить Богу демонизировать Resque. Я выбираю вариант 2.

A resque.god пример файла:

rails_env   = ENV['RAILS_ENV']  || "production"
rails_root  = ENV['RAILS_ROOT'] || "/path/to/my/app/current"
num_workers = rails_env == 'production' ? 5 : 2

num_workers.times do |num|
  God.watch do |w|
    w.dir      = "#{rails_root}"
    w.name     = "resque-#{num}"
    w.group    = 'resque'
    w.interval = 30.seconds
    w.env      = {"QUEUE"=>"critical,mailer,high,low", "RAILS_ENV"=>rails_env}
    w.start    = "bundle exec rake -f #{rails_root}/Rakefile resque:work"
    w.stop_signal = 'QUIT'
    w.stop_timeout = 20.seconds

    w.uid = 'myappuser'
    w.gid = 'myappuser'

    w.behavior(:clean_pid_file)

    # restart if memory gets too high
    w.transition(:up, :restart) do |on|
      on.condition(:memory_usage) do |c|
        c.above = 350.megabytes
        c.times = 2
        c.notify = {:contacts => ['maxime'], :priority => 9, :category => 'myapp'}
      end
    end

    # determine the state on startup
    w.transition(:init, { true => :up, false => :start }) do |on|
      on.condition(:process_running) do |c|
        c.running = true
      end
    end

    # determine when process has finished starting
    w.transition([:start, :restart], :up) do |on|
      on.condition(:process_running) do |c|
        c.running = true
        c.interval = 5.seconds
      end

      # failsafe
      on.condition(:tries) do |c|
        c.times = 5
        c.transition = :start
        c.interval = 5.seconds
      end
    end

    # start if process is not running
    w.transition(:up, :start) do |on|
      on.condition(:process_running) do |c|
        c.running = false
        c.notify = {:contacts => ['maxime'], :priority => 1, :category => 'myapp'}
      end
    end
  end
end
0 голосов
/ 24 ноября 2015

Вы можете управлять своими работниками с помощью этого сценария. Доступные команды:

rake resque:start_workers
rake resque:stop_workers
rake resque:restart_workers

Также имеется Resque-планировщик . Прокомментируйте эту строку, чтобы отключить ее:

pid = spawn(env_vars, 'bundle exec rake resque:scheduler', ops_s)
Process.detach(pid)
...