Ruby on rails Rails后台作业运行两次
我使用Rufus调度程序触发需要每1小时运行一次的后台作业Ruby on rails Rails后台作业运行两次,ruby-on-rails,scheduled-tasks,ruby-on-rails-5,rails-activejob,rufus-scheduler,Ruby On Rails,Scheduled Tasks,Ruby On Rails 5,Rails Activejob,Rufus Scheduler,我使用Rufus调度程序触发需要每1小时运行一次的后台作业 scheduler = Rufus::Scheduler.singleton scheduler.every '1h' do JobName.perform_now end 我在AWS中安装了Infra,对于生产,我有两个实例在ECS中运行该应用程序 发生的情况是调度程序将作业调度两次 实例A将作业安排在00:00:05:01,实例B将作业安排在00:00:05:05 工作并没有失败。我正在使用ActiveJob。我正在研究其他解
scheduler = Rufus::Scheduler.singleton
scheduler.every '1h' do
JobName.perform_now
end
我在AWS中安装了Infra,对于生产,我有两个实例在ECS中运行该应用程序
发生的情况是调度程序将作业调度两次
实例A将作业安排在00:00:05:01,实例B将作业安排在00:00:05:05
工作并没有失败。我正在使用ActiveJob。我正在研究其他解决方案,如延迟作业,但当存在多个实例时,也存在同样的问题
你们能提供另一种方法来解决这个问题吗?还是针对同一问题的解决方法?
“这在包含调度程序的Ruby进程多次启动的环境中非常有用。”
试试这个:
scheduler = Rufus::Scheduler.singleton(:lockfile => ".rufus-scheduler.lock")
scheduler.every '1h' do
JobName.perform_now
end
ECS实例不共享文件,最常见的是Zookeeper、Concur和Redis,所以您需要一个共享文件
下面是Zookeeper的示例:
类ZookeptScheduler您可以,但这不是正确的方法。仅在实例A上启动调度程序。我使用AWS两个类似的实例,因此锁不会起任何作用。我有一个docker,我正在将该docker部署到ECS容器中的多个实例中
class ZookeptScheduler < Rufus::Scheduler
def initialize(zookeeper, opts={})
@zk = zookeeper
super(opts)
end
def lock
@zk_locker = @zk.exclusive_locker('scheduler')
@zk_locker.lock # returns true if the lock was acquired, false else
end
def unlock
@zk_locker.unlock
end
def confirm_lock
return false if down?
@zk_locker.assert!
rescue ZK::Exceptions::LockAssertionFailedError => e
# we've lost the lock, shutdown (and return false to at least prevent
# this job from triggering
shutdown
false
end
end