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 для совместного использования файла блокировки, но это не правильный путь.

Запустите только планировщик на экземпляре A.

Другие вопросы по тегам