部署到Heroku时,当前的Sidekiq作业丢失了

时间:2016-02-22 13:31:25

标签: ruby-on-rails ruby heroku sidekiq

我有一个运行一段时间的Sidekiq作业,当我部署到Heroku并且作业正在运行时,它无法在几秒钟内完成。

没关系,因为这项工作旨在能够在需要时重新运行。

问题是作业丢失了(而不是放回redis并在部署后再次运行)。

我发现建议在heroku上设置:timeout: 8并尝试使用它,但它没有效果(也尝试过5次)。

当出现异常时,我会报告错误,但我没有看到任何异常。所以不确定会出现什么问题。

有关如何调试此问题的任何提示?

3 个答案:

答案 0 :(得分:5)

这实际上是sidekiq的功能 - 旨在引导您支付专业版: http://sidekiq.org/products/pro

  

可靠度

     

更可靠的消息处理。

     

云环境嘈杂且不可靠。看到超时?在延迟或性能方面出现大幅波动? Ruby VM崩溃或进程消失了吗?

     

如果Sidekiq进程在处理作业时崩溃,则该作业将丢失。

     

如果Sidekiq客户端在将作业推送到Redis时出现网络错误,则会引发异常并且不会传递作业。

     

Sidekiq Pro使用Redis的RPOPLPUSH命令确保在进程崩溃或获取KILL信号时不会丢失作业。

     

Sidekiq Pro客户端可以承受短暂的Redis中断或超时。它会在出错时在本地排队作业,并在连接恢复后尝试提供这些作业。

部署终止属于用户的所有进程,因此作业丢失。实际上你在那里做的并不多。

答案 1 :(得分:3)

免费版Sidekiq会在超时过后将未完成的作业推回Redis,默认为8秒。 Heroku提供了一个关闭过程10秒的过程。这意味着我们有2秒的时间让这些工作重新回到Redis 或者他们将会丢失。如果您的网络速度很慢,如果Redis服务器正在交换等,则可能无法满足2秒的截止日期并且作业丢失。

你走在正确的轨道上:一个答案就是降低超时时间,这样你就有更好的机会达到截止日期。但无法预测网络或交换延迟:即使5秒可能还不够。

在正常健康的条件下,事情应该按照设计运作。让您的机器保持健康(不拥挤的网络,充足的RAM),基本的提取应该很好。 Sidekiq Pro的可靠获取功能是对Sidekiq如何通过在Redis中保留工作以便不会丢失所有工作并解决所有这些问题的基本重新设计。但它也带来了严重的权衡:它比“基本”获取更复杂,更慢,更Redis密集。

简而言之,我不知道您失去工作的原因,但确保您的实例和Redis服务器运行正常且延迟较低。

https://github.com/mperham/sidekiq/wiki/Using-Redis#life-in-the-cloud

答案 2 :(得分:2)

正如@ mike-perham和@esse指出的那样,Sidekiq的设计方式是因为它的抓取机制可以解除工作。您可以选择解决此问题:

  1. 购买Sidekiq Pro(虽然reported导致同样的问题)
  2. 编写自己的抓取器(但这意味着您无法使用大多数第三方库,因为它们不能与您的自定义抓取器一起使用)
  3. 通过备份作业数据来模仿Sidekiq Pro的可靠提取。如果您是这样做的,请查看attentive_sidekiq gem,它就是这样做的。