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

时间:2015-09-08 15:14:28

标签: ruby aws-sdk sidekiq shoryuken

我正在将使用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 执行此操作的解决方法?

1 个答案:

答案 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小时。

  

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

     

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