Ответ 1
У меня была такая же проблема, и для меня это работает.
PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work >> worker1.log &
Вы также можете перенаправить STDERR в тот же файл журнала.
У меня есть рабочее рельсовое приложение с системой очереди resque, которая работает очень хорошо. Однако у меня нет хорошего способа фактически демонизировать рабочих-рескей.
Я могу начать их просто отлично, перейдя на rake resque: work QUEUE = "*", но я думаю, это не значит, что у вас должны быть ваши рабочие, работающие на переднем плане. По какой-то причине никто не обращает внимания на эту проблему. На официальной странице gizub resque вы можете сделать что-то вроде этого:
PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work
хорошо - он не работает в фоновом режиме здесь по крайней мере.
У меня была такая же проблема, и для меня это работает.
PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work >> worker1.log &
Вы также можете перенаправить STDERR в тот же файл журнала.
A +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
Возможно, вам понадобится повторно подключить любые подключения к DB, когда resque-pool виляет рабочих - проверьте документы.
Чтобы демонизировать процесс, вы можете использовать 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
Другим вариантом, который вы должны изучить, является использование resque pool gem для управления вашими работниками.
Вы можете запустить рескский пул в фоновом режиме, используя следующую команду:
resque-pool --daemon - производство окружающей среды
Изменена переменная среды BACKGROUND
в Resque 1.20; убедитесь, что вы не используете 1.19 или ниже.
Один хороший способ - использовать God для управления им. Он запускает демонзированную версию 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
Я также столкнулся с этой проблемой, я начинаю работу с капитаном, но у меня проблема
Наконец, я должен создать оболочку, позвольте ей спать 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
Я знаю, что это ситуационное решение. но он хорошо работает в моем проекте
Вы можете управлять своими сотрудниками с помощью этого script. Доступные команды:
rake resque:start_workers
rake resque:stop_workers
rake resque:restart_workers
Существует также resque-scheduler. Прокомментируйте эти строки, чтобы отключить его:
pid = spawn(env_vars, 'bundle exec rake resque:scheduler', ops_s)
Process.detach(pid)