2

我正在将使用sidekiq制作的后台作业处理服务迁移到基于Amazon SQS的shoryuken。使用sidekiq,您可以使用以下方法自定义重试模式:sidekiq_retry_in

class WorkerWithCustomRetry
    include Sidekiq::Worker
    sidekiq_options :retry => 5

    sidekiq_retry_in do |count|
        retry_count(count)
    end

    def self.retry_count(count)
    ...
    end
end

在我的例子中,retry_count返回基于外部配置的下一次重试的延迟。使用shoryuken时,只要消息未被消费者应用程序删除,SQS 就会自动处理重试。但是使用shoryuken,您可以通过使用更改延迟,retry_intervals文档仅说明如何设置固定值:

class MyWorker
    include Shoryuken::Worker

    shoryuken_options queue: 'default', retry_intervals: [360, 1200, 3600] # 5.minutes, 20.minutes and 1.hour

end

我需要使用与sidekiq相同的方式自定义重试延迟,使用retry_count根据外部数据返回不同值的方法。这是可能的还是存在使用shoryuken做到这一点的解决方法?

4

1 回答 1

3

目前 Shoryuken 仅支持指数退避的固定值,但您可以提交 PR 更改ExponentialBackoffRetry

# https://github.com/phstc/shoryuken/blob/290b1cb4c4c40f34881d7f7b7a3beda949099cf5/lib/shoryuken/middleware/server/exponential_backoff_retry.rb#L11

retry_intervals = worker.class.get_shoryuken_options['retry_intervals']

retry_intervals = if retry_intervals.respond_to? :call
                    retry_intervals.call(worker, queue, sqs_msg, body)
                  else
                    Array(retry_intervals)
                  end

因此,您将能够使用 proc 或固定值来设置retry_intervals,即:

class MyWorker
  include Shoryuken::Worker

  shoryuken_options queue: 'default', 
    retry_intervals: -> (worker, queue, sqs_msg, body) { worker.your_method(...) }
end

或者您可以删除默认值ExponentialBackoffRetry并添加您的:

Shoryuken.configure_server do |config|
  config.server_middleware do |chain|
    chain.remove Middleware::Server::ExponentialBackoffRetry
    chain.add YourExponentialBackoffRetry
  end
end

但请记住,SQS 不正式支持指数退避,它是在 Shoryuken 中使用 Visibility Timeout 实现的,最长可以延长到 12 小时。

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMes​​sageVisibility.html

您可以继续调用 ChangeMes​​sageVisibility 将可见性超时延长至最长 12 小时。如果您尝试延长超过 12 小时,该请求将被拒绝。

于 2015-09-17T01:30:45.673 回答