Sidekiq 笔记

配置 Sidekiq

首先,config/initializers/sidekiq.rb 我使用 metaprogramming,这样的好处是不同的 app,不同的 env,对应不同的 sidekiq queue。方便很多。

Sidekiq.configure_server do |config|
  config.redis = { namespace: [ Rails.application.railtie_name, Rails.env ].join("-") }
end

Sidekiq.configure_client do |config|
  config.redis = { namespace: [ Rails.application.railtie_name, Rails.env ].join("-") }
end

其次 config/sidekiq.yml

---
:concurrency: 5
:queues:
  - mailers
  - default

注意这个 mailers 的 queue,是 rails 的 ActionMailer 用的。要有他,#deliver_later 这个方法的发出的邮件任务才会被处理。

启动 Sidekiq

注意 sidekiq 是独立于 rails 的线程。在本地开发的时候,可以用 bundle exec sidekiq 来启动。远程的话 capistrano 就有个插件。

需要这个 gem:

gem 'capistrano', github: 'chengguangnan/capistrano2'
gem 'capistrano-sidekiq'

(需要注意的是, capistrano 我用的是自己的版本,因为 v3 问题太多。v2 官方又不维护了。)

然后 config/deploy.rb 里:

after "deploy:restart", "sidekiq:restart"

清空所有的 Queue

Sidekiq::Queue.all.each(&:clear)

性能

Sidekiq 的一个 worker 只使用一个 process,多个 threads。在 Ruby 里,一个 process 使用到一个 CPU core。所以即使你的 concurrency 设置的很高,也无法直接使用更多的 core。

如果你的 Job 需要直接使用大量的 CPU,那么可以打开多个 Sidekiq workers。运行这个命令多次 bundle exec sidekiq

还有一个问题,Sidekiq 是启动 Rails 来运行 Jobs 的,但是启动 Rails 很慢会不会影响呢?其实这个问题也不大,因为一个 Sidekiq worker 只需要启动一次 rails,多个 jobs 都可以在这一个 rails 里运行。