将 ActiveJob 与 Sidekiq 一起使用与单独使用 Sidekiq 相比的优势

Posted

技术标签:

【中文标题】将 ActiveJob 与 Sidekiq 一起使用与单独使用 Sidekiq 相比的优势【英文标题】:Advantages when using ActiveJob with Sidekiq compare with Sidekiq alone 【发布时间】:2017-12-31 11:46:40 【问题描述】:

我正在阅读一些在线教程,这些教程告诉我们如何将 ActiveJob 与 Sidekiq 结合使用。但我不知道我们为什么要这样做。我看到 Sidekiq 具有 ActiveJob 的所有功能。

此外,在 Sidekiq 文档上:here

警告:通过 ActiveJob 进行作业重试,您会损失很多 Sidekiq 功能:

    Web UI 可见性(重试选项卡将为空) 您不能使用 Sidekiq::RetrySet API 遍历重试。 Sidekiq 的日志不会包含任何故障或回溯。 错误不会报告给 Sidekiq 的全局错误处理程序 许多高级 Sidekiq 功能(例如批处理)不适用于 AJ 重试。

这是一个信号,让我觉得我们不应该将 Sidekiq 与 ActiveJob 一起使用。我对 ActiveJob 的理解有误吗?将 ActiveJobs 与 sidekiq 一起使用有什么优势吗?

谢谢

【问题讨论】:

那个 wiki 页面只是告诉你不要使用 ActiveJob 的重试,仅此而已。它并没有告诉你不要使用 ActiveJob。 @SergioTulentsev 非常感谢。根据您的评论和托尼文森特的回答,我可以理解一张图片。在您看来,您更喜欢在 SIdekiq 之上使用 ActiveJob 吗? (因为在这种情况下,我们必须接受这个解决方案中的一些弱点)例如重试作业。谢谢 我使用 ActiveJob 而不是 sidekiq,是的。 【参考方案1】:

Active Job 是队列技术之上的一个抽象层。

理论上,它允许您对一个通用接口进行编程,而不管您在下面使用什么。

听起来不错吧?嗯,在实践中,直接使用 Sidekiq 会好很多。

大多数 Ruby/Rails 商店都使用 Sidekiq。您永远不会将 Sidekiq 换成其他队列技术,而且万一您这样做了,Active Job 也不会像您想象的那样为您节省很多工作。 Sidekiq and Active Job don't work well together。在旧版本中情况更糟。除非您使用的是 Rails 6.0.2+ 和 Sidekiq 6.0.4,否则 Sidekiq 重试不适用于 Active Job。如果您使用的是 5.1 之前的 Rails 版本,则通过 Active Job 重试根本不起作用,除非您使用 Sidekiq 中间件重新发明***或添加另一个您并不真正需要的第三方依赖项。 Active Job adds a lot of overhead,这只是基准测试中捕获的性能开销。更重要的是,除了了解 Sidekiq 的工作原理之外,还必须了解 Active Job 的工作原理会带来认知开销。层数越多越复杂,即使看起来不像。 您无法看到重试和错误,因为活动作业有自己的重试机制。只有在 Active Job 重试次数用尽并将例外情况冒泡到 Sidekiq 时,它们才会在 Sidekiq 中可见。 Lev 提到的 GlobalId 功能?这种魔法导致更多的侦探工作。更喜欢显式代码,而不是隐藏行为以节省一行并误解代码实际在做什么。

【讨论】:

【参考方案2】:

对我来说,ActiveJob 的主要特点是对 GlobalId 的支持。比较:

Sidekiq

class SomeJob
  include Sidekiq::Worker
  def perform(record_id)
    record = Record.find(record_id)
    record.do_something
  end
end
SomeJob.perform_async(record.id)

ActiveJob

class SomeJob < ApplicationJob
  def perform(record)
    record.do_something
  end
end

SomeJob.perform_later(record)

方便又干净! ?

关于重试 - 是的,这是个问题,我不知道为什么 ActiveJob 中忽略了为底层系统配置每个作业的参数的功能。就解决方法而言,可以使用 gem activejob-retry:

class SomeJob
  include ActiveJob::Retry.new(strategy: :exponential, limit: 0)
end

这会禁用 ActiveJob 的重试,而 Sidekiq 的重试仍然有效。可以通过Sidekiq.default_worker_options['retry'] = 2在配置文件中配置sidekiq的重试

更新

重试问题已在 Sidekiq 6.0 ? 中修复

【讨论】:

【参考方案3】:

来自 Rails ActiveJob guide

重点是确保所有 Rails 应用程序都有工作 基础设施到位。然后我们可以拥有框架功能和其他 gems 建立在此之上,无需担心 API 各种作业运行器之间的差异,例如延迟作业和 回复。选择您的排队后端变得更加可操作 那么关心。而且您无需在它们之间切换 不得不重写你的工作。

ActiveJob 所做的基本上是标准化作业队列的 API 接口。这将帮助您轻松地从一个工作后端切换到另一个工作后端。

当您将 Sidekiq 与 ActiveJob 一起使用时,您可以从 sidekiq 提供的好东西中受益,但真正的问题是当您发现另一个队列器最适合您的应用程序时,ActiveJob 允许您切换到您选择的作业队列器一个班轮

# application.rb
config.active_job.queue_adapter = :sidekiq

【讨论】:

非常感谢。但是,如果我们在 sidekiq 之上使用 ActiveJob,那么重试作业(sidekiq 文档中提到)等一些缺点又如何呢?你认为在这种情况下我们应该更喜欢使用 ActiveJob(并且失去了一些其他有用的功能)吗?谢谢。 @TrầnKimDự 完全由您决定。问问自己你真的需要 Sidekiq 的重试标签吗?您是否需要 Sidekiq 批处理等。如果答案是肯定的,请使用 sidekiq,毕竟 sidekiq 是一个维护良好的项目 @TrầnKimDự 如果您要部署到 Heroku,您可以在与应用程序相同的服务器上使用 Suckerpunch,但 Sidekiq 需要另一个工作人员。

以上是关于将 ActiveJob 与 Sidekiq 一起使用与单独使用 Sidekiq 相比的优势的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ApplicationMailer(或 ActionMailer)设置为默认使用 Activejob/sidekiq

ActiveJob + Sidekiq 6.0.3:如何写入日志文件?

使用 Sidekiq 进行活动作业并获取 ActiveJob::DeserializationError

如何使用 ActiveJob 设置 Sidekiq 的重试次数?

Sidekiq Rails 4.2使用活动作业还是工作者?有什么不同

Sidekiq Rails 4.2 使用 Active Job 还是 Worker?有啥不同