禁用与Sidekiq一起使用的ActiveJob的自动重试功能

37

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

我知道只使用Sidekiq的话,我们只需要将 `retry: false` 添加到 worker 类中即可禁用自动重试。

sidekiq_options :retry => false

如此提到:https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration

但它似乎不能与ActiveJob和Sidekiq一起使用。

我也知道完全禁用重试的解决方案,就像这里建议的那样:https://stackoverflow.com/a/28216822/2431728

但这不是我需要的行为。

6个回答

27

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

4
实际上,您可以根据此处所示的方法删除 RetryJobs 中间件。 - gerry3
4
Sidekiq内置了一种全局关闭重试的方法:Sidekiq.default_worker_options = { retry: 0 } - Ari
2
@Ari 我不相信这对ActiveJob有效...只适用于没有AJ的本地Sidekiq工作者。 - courtsimas
@courtsmas Sidekiq::Middleware::Server::RetryJobs在5.0.0中已被删除,因此现在似乎唯一的禁用方法是Sidekiq.options[:max_retries] = 0 - Foton

8

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


3
即使我们使用初始化程序,并且设置如下:Sidekiq.default_worker_options = { 'backtrace' => 5, 'retry' => 3 } - Pratik Bothra

8

您可以捕获异常,而不是重试或配置重试:

  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集成的重试


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

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

1
如果您想禁用重试(或添加其他Sidekiq选项)以应用于来自gem的ActiveJob(例如ActionMailbox::RoutingJob),则可以使用此方法(适用于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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接