用 upstart 管理 sidekiq 进程

这是在之前一个项目的生产环境(基于 Ubuntu 14.04 LTS)中通过 upstart 管理 sidekiq 进程的部署流程,昨天看到 RubyChina 上一个帖子上的相关讨论,于是把自己的部署方式也分享出来。

第一步:修改用户目录下的 ~/.bash_profile 文件,在文件末尾增加
[[ -s "$HOME/.profile" ]] && source $HOME/.profile
第二步:修改用户目录下的 ~/.profile 文件

这里假设服务器用 rbenv 管理 Ruby 版本,所以需要在 ~/.profile 文件中增加下面四行 rbenv 相关的配置

export PATH="$HOME/.rbenv/bin:$PATH"  
eval "$(rbenv init -)"  
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"  
export RAILS_ENV=production  
第三步:创建 sidekiq 的 upstart 配置文件

配置文件路径 /etc/init/sidekiq.conf

注意根据实际部署的用户目录和项目路径修改配置文件中的 HOME/path/to/project/current

# /etc/init/sidekiq.conf - Sidekiq config

description "Sidekiq Background Worker"

start on runlevel [2345]  
stop on runlevel [016]

setuid deploy  
setgid deploy  
env HOME=/home/deploy

respawn  
respawn limit 3 30

reload signal USR1

script  
exec /bin/bash <<'EOT'  
  [ -f $HOME/.bash_profile ] && . $HOME/.bash_profile

  cd $HOME/path/to/project/current
  exec bundle exec sidekiq -e production -C config/sidekiq.yml -L log/sidekiq.log
EOT  
end script  
第四步:让 deploy 用户可以免 sudo 密码直接执行 upstart 管理命令
$ sudo echo "deploy ALL = (root) NOPASSWD: /sbin/start sidekiq, /sbin/stop sidekiq, /sbin/restart sidekiq, /sbin/reload sidekiq, /sbin/status sidekiq" >> /etc/sudoers

用于管理 sidekiq 进程的 Shell 命令

$ sudo start sidekiq
$ sudo stop sidekiq
$ sudo restart sidekiq
$ sudo reload sidekiq
$ sudo status sidekiq
第五步:配置 Mina 部署脚本,在部署过程中暂停并重启 sidekiq
# mina 的 deploy.rb 中关于 sidekiq 的管理任务
namespace :sidekiq do  
  [:start, :stop, :restart, :reload, :status].each do |command|
    desc "Run upstart task: #{command} sidekiq"
    task command do
      queue "sudo #{command} sidekiq"
    end
  end
end  

deploy 开始阶段暂停 sidekiq 接受新任务

invoke :'sidekiq:reload'

deploy 完成阶段重启 sidekiq 进程

invoke :'sidekiq:restart'

备注: reload 指令在 sidekiq.conf 中被配置用于向进程发送 USR1 信号,sidekiq 收到 USR1 信号后,会停止接受新任务,但是不影响当前正在执行的任务。