与单独使用 Sidekiq 相比,将 ActiveJob 与 Sidekiq 结合使用时的优势

Advantages when using ActiveJob with Sidekiq compare with Sidekiq alone

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

此外,在 Sidekiq 文档上:here

Warning: by doing job retry through ActiveJob, you lose a lot of Sidekiq functionality:

  1. Web UI visibility (the Retries tab will be empty)
  2. You cannot iterate through retries with the Sidekiq::RetrySet API.
  3. Sidekiq's log will not contain any failures or backtraces.
  4. Errors will not be reported to Sidekiq's global error handlers
  5. Many advanced Sidekiq features (e.g. Batches) will not work with AJ retries.

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

谢谢

来自 rails ActiveJob guide

The main point is to ensure that all Rails apps will have a job infrastructure in place. We can then have framework features and other gems build on top of that, without having to worry about API differences between various job runners such as Delayed Job and Resque. Picking your queuing backend becomes more of an operational concern, then. And you'll be able to switch between them without having to rewrite your jobs.

基本上 ActiveJob 所做的是标准化作业排队器的 API 接口。这将帮助您轻松地从一个作业后端更改为另一个作业后端。

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

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

对我来说,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

中修复

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 的工作原理,这会产生认知开销。层数越多越复杂,即使它看起来不像。
  • 您无法看到重试和错误,因为活动作业有自己的重试机制。只有在活动作业重试耗尽并向 Sidekiq 冒出异常时,它们才会在 Sidekiq 中可见。
  • Lev 提到的 GlobalId 功能?这种魔法会带来更多的侦探工作。更喜欢显式代码,而不是隐藏行为以节省一行并误解代码的实际作用。