我正在将使用sidekiq制作的后台作业处理服务迁移到shoryuken,该服务基于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_count
根据外部配置返回下次重试的延迟。
使用 shoryuken 重试将返回到SQS,只要消息不被消费者应用程序删除,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
我需要使用retry_count
方法自定义与 sidekiq 相同的重试延迟,该方法根据外部数据返回不同的值。这是否可行或确实存在使用 shoryuken 执行此操作的解决方法?
答案 0 :(得分:3)
目前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小时。
您可以继续调用ChangeMessageVisibility将可见性超时扩展到最多12小时。如果您尝试延长超过12小时,请求将被拒绝。