原贴 http://lanvige.github.io/2014/06/10/sidekiq-in-rails/
Image modify from whitepages
http://sidekiq.org/
https://github.com/mperham/sidekiq
http://railscasts.com/episodes/366-sidekiq
阅读前需要了解 Redis、Background Job 等概念,本文自动化部署使用的是 Capistrano 3。
$ gem install sidekiq
# Installing connection_pool 2.0.0
# Installing redis 3.0.7
# Installing redis-namespace 1.4.1
# Installing sidekiq 3.1.3
将 Redis 的配置信息放到 Rails 4 中的secrets.yml
中:
redis: &redis
redis_server: 'localhost'
redis_port: 6379
redis_db_num: 0
redis_namespace: 'highlander_sidekiq'
development:
<<: *redis
在initializers
下新建sidekiq.rb
文件,用来初始化 Redis 和 Sidekiq config
redis_server = Rails.application.secrets.redis_server
redis_port = Rails.application.secrets.redis_port
redis_db_num = Rails.application.secrets.redis_db_num
redis_namespace = Rails.application.secrets.redis_namespace
Sidekiq.configure_server do |config|
p redis_server
config.redis = { url: "redis://#{redis_server}:#{redis_port}/#{redis_db_num}", namespace: redis_namespace }
end
Sidekiq.configure_client do |config|
config.redis = { url: "redis://#{redis_server}:#{redis_port}/#{redis_db_num}", namespace: redis_namespace }
end
命令后加上 --help
可以看到其配置参数:
$ bundle exec sidekiq --help
-c, --concurrency INT processor threads to use
-d, --daemon Daemonize process
-e, --environment ENV Application environment
-g, --tag TAG Process tag for procline
-i, --index INT unique process index on this machine
-q, --queue QUEUE[,WEIGHT] Queues to process with optional weights
-r, --require [PATH|DIR] Location of Rails application with workers or file to require
-t, --timeout NUM Shutdown timeout
-v, --verbose Print more verbose output
-C, --config PATH path to YAML config file
-L, --logfile PATH path to writable logfile
-P, --pidfile PATH path to pidfile
-V, --version Print version and exit
-h, --help Show help
可以通过 linux cli 的方式,使用添数来启动 sidekiq: bundle exec sidekiq -q queue_name_1,queue_name_2
,也可以将这些参数放到 yml 中,通过 -C 参数来启动 bundle exec sidekiq -C config/sidekiq.yml
sidekiq 启动配置文件
:concurrency: 5
:pidfile: tmp/pids/sidekiq.pid
:queues:
- default
- [myqueue, 2]
development:
:concurrency: 5
staging:
:concurrency: 10
production:
:concurrency: 20
class SmsWorker
include Sidekiq::Worker
def perform(name, count)
# do something
p name
end
end
配置好这些东西,就可以对刚才写的 SmsWorker 进行测试了。
首先,要启动 Sidekiq:
$ bundle exec sidekiq -C config/sidekiq.yml ✘
"localhost"
2014-06-10T05:08:07Z 36163 TID-ox8pyjylc INFO: Booting Sidekiq 3.1.3 with redis options {:url=>"redis://localhost:6379/0", :namespace=>"highlander_sidekiq"}
s
ss
sss sss ss
s sss s ssss sss ____ _ _ _ _
s sssss ssss / ___|(_) __| | ___| | _(_) __ _
s sss \___ \| |/ _` |/ _ \ |/ / |/ _` |
s sssss s ___) | | (_| | __/ <| | (_| |
ss s s |____/|_|\__,_|\___|_|\_\_|\__, |
s s s |_|
s s
sss
sss
在另一个 Term 中使用 Rails Console 进行测试
$ rails c
# 调用perform
SmsWorker.perform_async 'Hello World', 0
就可以在 sidekiq 的调试窗口中看到输出了。
添加 gem capistrano-sidekiq添加到 Rails Project
gem 'capistrano-sidekiq' , group: :development
然后,项目中运行'cap -vT',可以看到添加下面这些有关 sidekiq 的命令。
cap sidekiq:quiet # Quiet sidekiq (stop processing new tasks)
cap sidekiq:respawn # Respawn missing sidekiq proccesses
cap sidekiq:restart # Restart sidekiq
cap sidekiq:rolling_restart # Rolling-restart sidekiq
cap sidekiq:start # Start sidekiq
cap sidekiq:stop # Stop sidekiq
(x)Cap 2.x 中可以配置 cmd 来选择 sidekiq.yml 进行启动,但 Cap 3.x 中就只能过配在 stage 下纯代码的方式来配置 (x),后来问了下作者,sidekiq_config 就是用来在 3.x 中使用 yml 来启动的:
以下为 cap-sidekiq 的参数配置和其默认值:
:sidekiq_default_hooks => true
:sidekiq_pid => File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid')
:sidekiq_env => fetch(:rack_env, fetch(:rails_env, fetch(:stage)))
:sidekiq_log => File.join(shared_path, 'log', 'sidekiq.log')
:sidekiq_options => nil
:sidekiq_require => nil
:sidekiq_tag => nil
:sidekiq_config => nil
:sidekiq_queue => nil
:sidekiq_timeout => 10
:sidekiq_role => :app
:sidekiq_processes => 1
:sidekiq_concurrency => nil
sidekiq_default_hooks 是 capistrano-sidekiq 提供的默认的 hooks,在 cap 的指定 task 前后指行相应的 task,如发布前关闭 sidekiq,发布完后启动 Sidekiq。具体见代码。如果不需要,可以设置该值为 false,即可关闭。
示例如下,在 stage 中配置 concurrency pool size 和 named queue 的值
## sidekiq
set :sidekiq_concurrency, 10
set :sidekiq_queue, ['client_sms,2', 'client_emails,5', 'default,3', 'foo']
## or use config.yml file
set :sidekiq_config, "#{current_path}/config/sidekiq.yml"
会启动如下命令:
RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.2 ~/.rbenv/bin/rbenv exec bundle exec sidekiq --index 0 --pidfile /home/ares/apps/highlander/shared/tmp/pids/sidekiq.pid --environment production --logfile /home/ares/apps/highlander/shared/log/sidekiq.log --queue sms, notification --concurrency 10 --daemon
这里有一个问题,我第一天使用时,花了半天去调试,发现是'set pry'的问题 Not started sidekiq after deploy - if pty is true。
当初忘记为什么,在 deploy.rb 中设置 pry 为 true 了,只好在 production stage 的配置中,设置回来。
set :pty, false
# 查看sidekiq进程
$ ps aux | grep sidekiq
gem 'sinatra'
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'
这样,就可以在页面上看到 sidekiq 的运行情况了。更多详情见:sidekiq Monitoring
http://railscasts.com/episodes/366-sidekiq?view=asciicast
http://stackoverflow.com/questions/14825565/sidekiq-deploy-to-multiple-environments