我正在使用Rufus Scheduler来触发需要每1小时运行一次的后台作业。
scheduler = Rufus::Scheduler.singleton
scheduler.every '1h' do
JobName.perform_now
end
我在AWS中进行了Infra设置,并且在生产中,我有2个实例在ECS中运行APP。
调度程序会安排作业两次。
实例A在00:00:05:01安排工作,实例B安排在00:00:05:05
工作没有失败。我正在使用ActiveJob。我正在研究其他解决方案,比如延迟Job,但是当有多个实例时,它会遇到同样的问题。
你们可以提供另一种方法来解决这个问题吗?或者相同的解决方法?
答案 0 :(得分:1)
https://github.com/jmettraux/rufus-scheduler#lockfile--mylockfiletxt
“这在持有调度程序的Ruby进程多次启动的环境中很有用。”
试试这个:
scheduler = Rufus::Scheduler.singleton(:lockfile => ".rufus-scheduler.lock")
scheduler.every '1h' do
JobName.perform_now
end
答案 1 :(得分:1)
您需要distributed lock,因为ECS实例不共享文件,最常见的是Zookeeper,Consul和Redis。
在Zookeeper的示例下面,from the docs:
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
你可能use EFS to share a lockfile,但这不是正确的方法。
答案 2 :(得分:0)
仅启动实例A上的调度程序。