Rails Background Jobs, работающие дважды
Я использую Rufus Scheduler для запуска фоновых заданий, которые должны запускаться каждые 1 час.
scheduler = Rufus::Scheduler.singleton
scheduler.every '1h' do
JobName.perform_now
end
У меня есть настройки Infra в AWS, и для производства у меня есть 2 экземпляра, на которых запущено приложение внутри ECS.
Что происходит, так это то, что планировщик планирует задания дважды.
Экземпляр A планирует работу в 00:00:05:01, а экземпляр B - в 00:00:05:05
Работа не терпит неудачу. Я использую ActiveJob. Я искал другие решения, такие как отложенное задание, но с той же проблемой, когда есть несколько экземпляров.
Ребята, можете ли вы предложить альтернативный подход к решению этой проблемы? Или обходной путь для того же?
3 ответа
https://github.com/jmettraux/rufus-scheduler
"Это полезно в средах, где процесс Ruby, содержащий планировщик, запускается несколько раз".
Попробуй это:
scheduler = Rufus::Scheduler.singleton(:lockfile => ".rufus-scheduler.lock")
scheduler.every '1h' do
JobName.perform_now
end
Вам нужна распределенная блокировка, поскольку экземпляры ECS не обмениваются файлами, наиболее распространенными из которых являются Zookeeper, Consul и Redis.
Ниже приведен пример с Zookeeper из документов:
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
Возможно, вы можете использовать EFS для совместного использования файла блокировки, но это не правильный путь.