Gem Sidekiq 精通 36 分钟

lanvige · 发布于 2014年6月12日 · 最后由 liuzelei 回复于 2016年12月26日 · 15437 次阅读
96
本帖已被设为精华帖!

原贴 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。

Rails中配置Sidekiq

$ 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

sidekiq 配置参数

命令后加上 --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

Worker

class SmsWorker
  include Sidekiq::Worker

  def perform(name, count)
    # do something
    p name
  end
end

Run

配置好这些东西,就可以对刚才写的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的调试窗口中看到输出了。

Deploy with Capistrano

添加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,即可关闭。

Rails中的Cap配置示例:

示例如下,在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

REF::

http://railscasts.com/episodes/366-sidekiq?view=asciicast
http://stackoverflow.com/questions/14825565/sidekiq-deploy-to-multiple-environments

共收到 30 条回复
12260
xiongxin8802 · #1 · 2014年6月12日

菜鸟求科普。。这是什么作用的

4215
chenge · #2 · 2014年6月12日 3 个赞

#1楼 @xiongxin8802 不爱搜索的程序员都不是好的CEO

12212
rco · #3 · 2014年6月12日

原来是用 resque 及 resque-scheduler。有此篇介绍,方便快速入手。

13125
qifengle · #4 · 2014年6月12日
  1. redis需要2.6以上。
  2. 对于同一台机器有不同的环境,pidfile需要配置为不同文件。
  3. sidetiq for scheduler ?
96
nickcen · #5 · 2014年6月12日

跟delayed_job之类是什么关系,优缺点之类的了?

8043
teddy_1004 · #6 · 2014年6月12日

#5楼 @nickcen 比 Delayed Job 快很多,Delayed Job 适合做小量的、耗时短的后台作业。多的还是得交给像 Resque、Sidekiq 这些。

2019
neverlandxy_naix · #7 · 2014年6月12日

没有涉及到子worker的管理和子worker的计算, 如果加上这些就好了

2443
wppurking · #8 · 2014年6月12日

写得好详细~ 我也搭个顺风车, 共享个我为公司内编写的 Sidekiq 使用详解 😄

5178
zhang_soledad · #9 · 2014年6月12日

标记一下 以后再看

96
lanvige · #10 · 2014年6月12日

@neverlandxy_naix 这一块,要过几天加上 :)

2019
neverlandxy_naix · #11 · 2014年6月12日

#10楼 @lanvige 赞, 强烈期待更新

10912
spiderxu · #12 · 2014年6月12日

最近项目刚用到sidekiq,长见识了。

96
lanvige · #13 · 2014年6月12日

@wppurking 赞,正是我接下来要写的。推荐 +1

5763
yuh · #14 · 2014年6月12日

原来是pty的问题,被cap那个坑已经折磨很久了。

1680
justin · #15 · 2014年6月12日

:plus1:

1553
Peter · #17 · 2014年6月12日

👏

515
kewin · #18 · 2014年6月12日

:plus1: :

328
bluecoda · #19 · 2014年6月13日

这。。。离精通差远了吧

8137
xifengzhu · #20 · 2014年6月13日

resque 貌似也是根据delay job封装的吧

96
lanvige · #21 · 2014年6月13日

#19楼 @bluecoda 哈哈,你看完还没用36小时的吧,关于work, queue的东西我没来得及整理,只是把安装,自动化发布给放了出来。

其实这种东西看别人的永远无法精通。只会增加几分好感罢了。

96
lanvige · #22 · 2014年6月13日

#20楼 @xifengzhu 对,sidekiq 就是在 resque 上面改进的,性能高一些,一般来说没什么差别。只是选型时选了这个。

9861
wangping · #23 · 2014年6月16日

大善~

6829
hiveer · #24 · 2014年6月20日

跟resque如此相似,希望LZ能将他们做个对比,期待后续!

4436
zzwzj · #25 · 2014年6月24日

按照楼主得配置,传到服务器出现错误: URI::InvalidURIError: the scheme redis does not accept registry part: : (or bad hostname?)

5489
rubyu2 · #26 · 2014年6月30日

标题太虎,改成入门吧。。。

7292
cestivan · #27 · 2014年7月11日

补充一点:

1、用devise的话,有个devise-async的gem,加入之后必须给sidekiq添加一个mailer的queue(或者将devise-async的queue改成sidekiq的默认queue——default)。

2、mina部署的话用mina-sidekiq的gem,很好用。

871
naitnix · #28 · 2014年10月11日

#25楼 @zzwzj 这个你是怎么解决的?

9770
clarkyi · #29 · 2015年1月16日

如果多个项目用sidekiq的话会有命名空间的问题

4559
liuzelei · #30 · 2016年12月26日

我特喵的今天就被这个load config给坑了。。。。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册