gpt4 book ai didi

ruby-on-rails-4 - rufus-scheduler 在分离模式下运行在 Rails+Unicorn 之上时不进行调度

转载 作者:行者123 更新时间:2023-12-01 23:48:08 25 4
gpt4 key购买 nike

我正在使用 rufus-scheduler在我的 Ruby on Rails 应用程序中安排一些作业。相关规范:

  • ruby :2.1.2p95
  • 导轨:4.1.1
  • Rufus-调度程序:3.0.9

当我使用“rails s unicorn”运行应用程序时,调度程序运行得非常好。但是,当我使用“-d”选项分离服务器时,计划的作业永远不会运行。

这是我的 config/initializers/task_scheduler.rb 文件:

require 'rubygems'
require 'rufus/scheduler'
require 'rake'

load File.join(Rails.root, 'lib', 'tasks', 'send_emails.rake')
MyApplication::Application.load_tasks
scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler.lock")

if (!MyApplication.rake?)
unless scheduler.down?

Rails.logger.info "OK"

scheduler.interval("1m") do
Rails.logger.info "yup"
system ("rake send_emails:mail_users")
end

end
end

和我的 unicorn.rb 文件:

worker_processes 2
preload_app true
timeout 30

before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end

defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end

defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end

“!MyApplication.rake?” line 是为了防止 rake 任务也运行调度程序;我已将此行添加到我的 Rakefile 中:

MyApplication.rake = true

当我查看我的日志时,我注意到正在打印“OK”行,所以我相信调度程序正在正确初始化,但是从未打印作业的记录器行并且 rake 任务没有运行。

此时我不确定问题出在我的 unicorn 配置上,还是我的调度程序配置上。任何帮助将不胜感激!

编辑 1:

“rails s”的日志输出

I, [2015-01-28T20:11:05.179505 #79141]  INFO -- : listening on addr=0.0.0.0:3000 fd=12
Before
Before
I, [2015-01-28T20:11:05.426386 #79141] INFO -- : master process ready
After
After
I, [2015-01-28T20:11:05.434392 #79143] INFO -- : worker=0 ready
I, [2015-01-28T20:11:05.435585 #79144] INFO -- : worker=1 ready
yup

“rails s -d”的日志输出

OK
Before
Before
After
After

正如 jmettraux 所建议的,当使用“-d”选项时,调度程序似乎在 fork 后丢失了。我做了一些调整,将调度程序移到了一个类中,并从 after_fork block 中调用了初始化程序:

lib/scheduler.rb

require 'rufus/scheduler'
class Scheduler

def self.startup
Rails.logger.info "startup"
load File.join(Rails.root, 'lib', 'tasks', 'send_emails.rake')
USA::Application.load_tasks
scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler.lock")

if (!USA.rake?)
Rails.logger.info "nope"
unless scheduler.down?
Rails.logger.info "OK"

scheduler.interval("1m") do
Rails.logger.info "yup"
system ("rake send_emails:mail_users")
end

scheduler.join

end
end
end

end

unicorn .rb:

worker_processes 2
preload_app true
timeout 100

load File.join(Rails.root, 'lib', 'scheduler.rb')

...

after_fork do |server, worker|
Rails.logger.info "After"
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end

defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection

Scheduler::startup

end

但是,当启动“rails s -d”时,这会失控并且 worker 会不断地被生成和杀死:

Before
Before
After
After
startup
startup
Before
After
Before
startup
After
startup
Before
After
startup

我确定我从 after_fork block 启动调度程序的实现可能是罪魁祸首,但我不确定到底是什么导致了这种情况。

编辑2

我傻了。我正在使用 gist那个 jmettraux 链接了,但是当我试图让它在我的应用程序中工作时,我把它砍掉了。我返回并从头开始启动我的 unicorn.rb 和 scheduler.rb,它现在可以正常工作了!

最佳答案

您应该在 after_fork block 中添加一些 Rails.logger.info("XXX") 以查看它是发生在 OK 之前还是之后。

似乎有人遇到了同样的问题并想出了一些办法:https://gist.github.com/jkraemer/3851917它已经四岁了,但它可以给你一些灵感。

它的“要点”似乎是在 after_fork block 中运行/启动 rufus-scheduler(这样它的线程就不会在 fork 中被杀死)。

关于ruby-on-rails-4 - rufus-scheduler 在分离模式下运行在 Rails+Unicorn 之上时不进行调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28204763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com