33

有没有办法使用 ActiveJob 和 Sidekiq 禁用自动重试?

我知道只有 Sidekiq,我们只需要放

sidekiq_options :retry => false

如此处所述:https ://github.com/mperham/sidekiq/wiki/Error-Handling#configuration

但它似乎不适用于 ActiveJob 和 Sidekiq。

我也知道这里提出的完全禁用重试的解决方案:https ://stackoverflow.com/a/28216822/2431728

但这不是我需要的行为。

4

6 回答 6

21

从 开始sidekiq 6.0.1,可以将以下内容传递给 ActiveJob 工作人员以防止其重试:

class ExampleJob < ActiveJob::Base
  sidekiq_options retry: false

  def perform(*args)
    # Perform Job
  end
end

更多信息:https ://github.com/mperham/sidekiq/wiki/Active-Job#customizing-error-handling

编辑:

据此,也需要 Rails6.0.1或更高版本。

于 2020-01-15T15:03:24.907 回答
19

好的,谢谢你的回答。

仅供参考,我还在 ActiveJob Github 存储库上与此主题相关的问题中提出了问题:https ://github.com/rails/activejob/issues/47

DHH 回答了我一个我没有测试过但可以完成工作的解决方案。

就个人而言,我最后把它放在一个初始化程序中,以便全局禁用 Sidekiq 重试,它运行良好:

Sidekiq.configure_server do |config|
   config.server_middleware do |chain|
      chain.add Sidekiq::Middleware::Server::RetryJobs, :max_retries => 0
   end
end
于 2015-02-10T08:48:45.530 回答
8

无法使用 ActiveJob 配置有关 Sidekiq 的任何内容。如果您不想使用默认值,请使用 Sidekiq Worker。

于 2015-02-09T16:27:47.760 回答
7

您可以赶上异常并且什么都不做,而是重试或配置重试:

  class ExampleJob < ActiveJob::Base
    rescue_from(StandardError) do |exception|
      Rails.logger.error "[#{self.class.name}] Hey, something was wrong with you job #{exception.to_s}"       
    end

    def perform
      raise StandardError, "error_message"
    end
  end

  class ExampleJob < ActiveJob::Base
    rescue_from(StandardError) do |exception|
      retry_job wait: 5.minutes, queue: :low_priority     
    end

    def perform
      raise StandardError, "error_message"
    end
  end

对于运行重试,您可以使用 retry_on 方法retry_on 方法文档

Sidekiq wiki 用于与 Active Job 集成重试

于 2016-11-09T08:49:17.140 回答
2

我也有同样的需求,即 ActiveJob 包装 Sidekiq 但想要支持 max_retries。我把它放在一个初始化程序中。如果在 ActiveJob 作业上定义了 #max_retries,它将用于设置重试次数。如果#ephemeral?已定义并返回 true,作业将不会重新运行,并且如果失败也不会转移到“死亡”。

class Foobar::SidekiqClientMiddleware
  def call(worker_class, msg, queue, redis_pool)
    aj_job = ActiveJob::Base.deserialize(msg['args'][0]) rescue nil
    msg['retry'] = aj_job.respond_to?(:max_retries) ? aj_job.max_retries : 5
    msg['retry'] = false if aj_job.respond_to?(:ephemeral?) && aj_job.ephemeral?
    yield
  end
end

Sidekiq.configure_client do |config|
  config.redis = { url: "redis://#{redis_host}:6379/12" }
  config.client_middleware do |chain|
    chain.add Foobar::SidekiqClientMiddleware
  end
end

Sidekiq.configure_server do |config|
  config.redis = { url: "redis://#{redis_host}:6379/12" }
  config.client_middleware do |chain|
    chain.add Foobar::SidekiqClientMiddleware
  end
end

注意:如果您的任何作业在执行时自己创建新作业,则将其添加到客户端和服务器的中间件链实际上很重要。

于 2015-07-02T20:52:23.490 回答
0

如果您想禁用ActiveJobfrom gems(如 for ActionMailbox::RoutingJob)的重试(或添加任何其他 Sidekiq 选项),您可以使用这种方法(Rails 6.0.2+)。

1)使用所需的 Sidekiq 选项创建一个模块(使用ActiveSupport::Concern

# lib/fixes/action_mailbox_routing_job_sidekiq_fix.rb

module ActionMailboxRoutingJobSidekiqFix
  extend ActiveSupport::Concern

  included do
    sidekiq_options retry: false
  end
end

2) 将其包含在初始化程序的作业类中。

# config/initializers/extensions.rb

require Rails.root.join('lib', 'fixes', 'action_mailbox_routing_job_sidekiq_fix')

Rails.configuration.to_prepare do
  ActionMailbox::RoutingJob.include ::ActionMailboxRoutingJobSidekiqFix
end

于 2020-02-19T08:45:40.873 回答