使用来自 Shoryuken 的 Amazon SQS 自定义重试延迟 (ruby)

Customizing retry delays with Amazon SQS from Shoryuken (ruby)

我正在迁移使用 sidekiq to shoryuken, which is based on Amazon SQS 制作的后台作业处理服务。 使用 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_countreturns 下一次重试的延迟基于外部配置。 使用 shoryuken 时,只要消息未被消费者应用程序删除,SQS 就会自动处理重试。但是,使用 shoryuken 您可以使用 retry_intervals 更改延迟,但 documentation 仅说明如何设置固定值:

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 方法,根据外部数据 returns 不同的值.这是可能的还是确实存在使用 shoryuken?

的解决方法

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

# 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 中使用可见性超时实现的,最多可以延长到 12 小时。

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html

You can continue to call ChangeMessageVisibility to extend the visibility timeout to a maximum of 12 hours. If you try to extend beyond 12 hours, the request will be rejected.