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

Posted

技术标签:

【中文标题】Sidekiq Rails 4.2 使用 Active Job 还是 Worker?有啥不同【英文标题】:Sidekiq Rails 4.2 Use Active Job or Worker? What's the differenceSidekiq Rails 4.2 使用 Active Job 还是 Worker?有什么不同 【发布时间】:2015-07-07 16:19:12 【问题描述】:

这是我的第一个异步处理作业,我正在我的应用程序中实现 Sidekiq 以进行后台处理。我会将它用于提醒电子邮件和应用内通知。我很困惑我应该使用 Active Job 来创建发送电子邮件的作业还是使用 Sidekiq Worker 来发送电子邮件。他们似乎在做同样的事情,Rails 4.2 Active Job 似乎很新……它是否取代了对 Sidekiq Worker 的需求?

下面是使用 Active Job 作业和 Sidekiq Worker 发送邮件代码的相同方法。我正在使用每当 gem 进行调度。

my_mailers.rb

class MyMailers < ActionMailer::Base

  def some_mailer(r.user_id)
    @user = User.find(r.user_id)
    mailer_name = "ROUNDUP"
    @email = @user.email
    @subject ="subject text"
    mail(to: @email, 
      subject: @subject,  
      template_path: '/notifer_mailers', 
      template_name: 'hourly_roundup.html',
      )
  end
end

使用 Sidekiq “Worker” some_worker.rb

class SomeWorker
  include Sidekiq::Worker

  def perform()
    @user = User.all
    @reminders = @user.reminders.select(:user_id).uniq.newmade
    @reminders.each do |r|
      MyMailers.some_mailer(r.user_id).deliver_later
    end
  end

end

使用活动作业“作业” some_job.rb

class SomeJob < ActiveJob::Base
  queue_as :mailer

  def perform()
    @user = User.all
    @reminders = @user.reminders.select(:user_id).uniq.newmade
    @reminders.each do |r|
      MyMailers.some_mailer(r.user_id).deliver_later
    end
  end

end

我的 When 调度程序中的两个示例 schedule.rb

require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
set :path, Rails.root
set :output, Rails.root.join('log', 'cron.log')

#using a worker
every 1.day, :at => '4:30 am' do
  runner SomeWorker.perform_async
end

#using a job
every 1.day, :at => '4:30 am' do
  runner SomeJob.perform_async
end

【问题讨论】:

【参考方案1】:

简短的回答是它们是同一个东西。 ActiveJob 将其称为 Job,而 Sidekiq 将其称为 Worker。我决定保持术语不同,以便人们能够区分两者。

您可以使用任何一种。请注意,ActiveJob 不提供对全套 Sidekiq 选项的访问权限,因此如果您想为您的工作自定义选项,您可能需要将其设为 Worker。

【讨论】:

感谢您的回答和出色的工作!一个非常相关的问题:仍然可以在邮件中使用旧语法 sidekiq 吗?例如UserMailer.delay.welcome_email(@user.id) 当然。所有“旧”的 API 仍然有效并且非常好用。 太棒了,这是让 sidekiq 提供其令人敬畏的重试功能的好方法 :) 了解这一点很有用❤ 幸运的是,从 sidekiq 6.0 版开始,还可以通过 ActiveJob 传递 sidekiq_options :) github.com/mperham/sidekiq/blob/master/6.0-Upgrade.md#whats-new【参考方案2】:

Rails 4.2 添加了 ActiveJob 以统一作业 API,但要异步运行它,您需要一个后台处理程序,这就是 sidekiq 的来源。

Sidekiq 已经有了它的工人类,但它也实现了新的活动作业类,所以它可以以任何方式工作。

但是,活动作业的好处是您可以更改后台处理程序而无需更改代码,前提是它们都支持您想要的功能(例如:在特定时间处理作业;具有多个优先级队列) .

rails api guide here 对支持活动作业的处理程序进行了很好的比较,包括每个处理程序支持的功能。如果你懒得看链接,这里是对照表:

|                   | Async | Queues | Delayed   | Priorities | Timeout | Retries |
|-------------------|-------|--------|-----------|------------|---------|---------|
| Backburner        | Yes   | Yes    | Yes       | Yes        | Job     | Global  |
| Delayed Job       | Yes   | Yes    | Yes       | Job        | Global  | Global  |
| Qu                | Yes   | Yes    | No        | No         | No      | Global  |
| Que               | Yes   | Yes    | Yes       | Job        | No      | Job     |
| queue_classic     | Yes   | Yes    | No*       | No         | No      | No      |
| Resque            | Yes   | Yes    | Yes (Gem) | Queue      | Global  | Yes     |
| Sidekiq           | Yes   | Yes    | Yes       | Queue      | No      | Job     |
| Sneakers          | Yes   | Yes    | No        | Queue      | Queue   | No      |
| Sucker Punch      | Yes   | Yes    | No        | No         | No      | No      |
| Active Job Inline | No    | Yes    | N/A       | N/A        | N/A     | N/A     |
| Active Job        | Yes   | Yes    | Yes       | No         | No      | No      |

【讨论】:

看起来即使您使用activejob并使用sidekiq设置它,它也属于sidekiq功能对吧? (因为目前我的重试仍在进行中)【参考方案3】:

我建议坚持使用本机 sidekiq 以获得更多功能。我偶尔也会遇到一些关于 ActiveJob 的奇怪序列化问题。 ActiveJob 在追求执行统一 API 的崇高目标的同时,正是出于这个原因限制了许多实现,并为现在的 IMO 提供了一点好处。就个人而言,我非常渴望在未来某个时间支付重写代码的可能价格(这可能永远不会发生,您不会为了好玩而交换应用程序的关键部分 - 比如activerecord vs mongodb)如果我决定将实现交换为更丰富的功能集。

【讨论】:

【参考方案4】:

根据文档,与 ActiveJob 相比,使用 Sidekiq::Worker 可能具有性能优势。

https://github.com/mperham/sidekiq/wiki/Active-Job#performance

【讨论】:

以上是关于Sidekiq Rails 4.2 使用 Active Job 还是 Worker?有啥不同的主要内容,如果未能解决你的问题,请参考以下文章

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

Sidekiq 3.4.2 和 Rails 4.2.0 出现“未定义方法 perform_at”错误

Rails:如何重启sidekiq?

在多线程 Rails 环境中使用 Redis 的最佳方式是啥? (彪马/Sidekiq)

Rails 6.1:Heroku 上的作业将使用 Async 而不是 Sidekiq

如何使用 Sidekiq 在 Rails 中 3 分钟后发送电子邮件?