Gem Sidekiq 精通 36 分钟

lanvige · 2014年06月12日 · 最后由 seven.lee 回复于 2019年02月22日 · 32624 次阅读
本帖已被管理员设置为精华贴

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

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

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

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

  1. redis 需要 2.6 以上。
  2. 对于同一台机器有不同的环境,pidfile 需要配置为不同文件。
  3. sidetiq for scheduler ?

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

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

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

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

标记一下 以后再看

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

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

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

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

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

:plus1: :

这。。。离精通差远了吧

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

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

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

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

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

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

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

补充一点:

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

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

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

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

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

这也能算精通?充其量就是个配置流程

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