【问题标题】:Disable automatic retry with ActiveJob, used with Sidekiq使用 ActiveJob 禁用自动重试,与 Sidekiq 一起使用
【发布时间】:2015-04-09 09:04:24
【问题描述】:

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

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

sidekiq_options :retry => false

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

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

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

但这不是我需要的行为。

【问题讨论】:

    标签: ruby-on-rails sidekiq rails-activejob


    【解决方案1】:

    好的,谢谢你的回答。

    仅供参考,我还在 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
    

    【讨论】:

    • 其实可以去掉RetryJobs中间件,如图here
    • Sidekiq 有一个内置的方式来全局关闭重试:Sidekiq.default_worker_options = { retry: 0 }
    • @Ari 我不相信这适用于 ActiveJob... 仅适用于没有 AJ 的本地 Sidekiq 工人
    • @courtsmas Sidekiq::Middleware::Server::RetryJobs 在 5.0.0 中被删除,所以现在看来​​唯一禁用的方法是 Sidekiq.options[:max_retries] = 0
    【解决方案2】:

    截至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

    编辑:

    根据this 这需要Rails 6.0.1 或更高版本。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 即使我们使用初始化器,设置如下? Sidekiq.default_worker_options = { 'backtrace' => 5, 'retry' => 3 }
      【解决方案4】:

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

        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 method doc

      Sidekiq wiki for retries with Active Job integration

      【讨论】:

        【解决方案5】:

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

        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
        

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

        【讨论】:

          【解决方案6】:

          如果您想从 gems 中为 ActiveJob 禁用重试(或添加任何其他 Sidekiq 选项)(例如 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
          
          

          【讨论】:

            猜你喜欢
            • 2017-12-31
            • 2016-01-13
            • 2016-12-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-29
            • 2017-06-21
            相关资源
            最近更新 更多