Sidekiq 是不是适合高度关键任务、需要一次性执行保证、需要单线程执行的任务?
Posted
技术标签:
【中文标题】Sidekiq 是不是适合高度关键任务、需要一次性执行保证、需要单线程执行的任务?【英文标题】:Is Sidekiq suitable for tasks that are highly mission critical, one-time execution guarrantee required, single threaded execution necessary?Sidekiq 是否适合高度关键任务、需要一次性执行保证、需要单线程执行的任务? 【发布时间】:2013-11-23 19:48:40 【问题描述】:示例场景:
付款处理和电子产品交付交易。
要求
-
每天大约有几千笔支付交易需要执行。每个大约需要 1 秒。 (所以整个过程大约需要一个小时)
事务必须在单个线程中线性处理(下一个事务必须在最后一个事务完成后才开始,强 FIFO 顺序是必要的)
每个支付交易都包含在一个数据库交易中,任何返回以回滚交易的东西都会被中止并放入另一个队列以进行手动错误处理。之后,它应该继续处理其余的交易。
重要性顺序
-
单次执行(如果失败,放入错误队列进行人工处理)
单螺纹
先进先出
Sidekiq 是否适合此类关键任务流程? sidekiq 能否满足所有这些要求?或者你会推荐其他替代品吗?您能否指出一些有关在 Rails 中处理付款的最佳做法?
Note: The question is not regarding whether to use stripe or ActiveMerchant for payment handling. It is more about the safest way to programmatically execute those processes in the background.
【问题讨论】:
【参考方案1】:是的,Sidekiq 可以满足所有这些要求。
要以串行方式一次处理一个事务,您可以启动一个并发为 1 的 Sidekiq 进程,该进程仅适用于该队列。该进程将按顺序一次处理一个队列中的作业。
要让失败的任务进入失败队列,您需要使用 Sidekiq Failures gem 并确保为该任务关闭重试。
为保证每个任务至少执行一次,您可以购买Sidekiq Pro并使用Reliable Fetch。如果 Sidekiq 崩溃,它将在重新启动时执行任务。这假设您将设置监控以确保 Sidekiq 进程保持运行。您可能还希望使您的任务具有幂等性,因此它不会两次编写相同的事务。 (理论上,在您的数据库事务提交之后,但在 Sidekiq 向 Redis 报告任务完成之前,该进程可能会崩溃。)
如果使用 Ruby 是一个限制条件,Sidekiq 可能是您最好的选择。我在 Ruby 中使用了几种不同的队列系统,但它们都没有 Sidekiq 那样的可靠性保证。
【讨论】:
【参考方案2】:在最后一个事务完成之前不能开始下一个事务
在那种情况下,我认为后台处理是合适的,只要您在完成上一个作业时创建下一个作业。
class Worker
include Sidekiq::Worker
def perform(*params)
# do work, raising exception if necessary
NextWorker.perform_async(params, here)
end
end
【讨论】:
以上是关于Sidekiq 是不是适合高度关键任务、需要一次性执行保证、需要单线程执行的任务?的主要内容,如果未能解决你的问题,请参考以下文章
两个垂直子元素需要适合父元素的 100% 高度,都是动态高度
Rspec 如何测试 Sidekiq 作业是不是计划在特定时间运行