Capistrano启动Sidekiq后进程莫名消失的技术求助
Capistrano v2启动Sidekiq Daemon模式进程消失的问题解决
我之前处理过一模一样的Capistrano v2 + Sidekiq场景问题,你的情况核心原因是:Capistrano在执行完任务后会关闭整个SSH会话,而Sidekiq的daemon进程虽然看似后台运行,但其实还和这个会话的标准输入/输出绑定,被会话关闭时的HUP信号终止了。这就解释了为什么直接SSH执行命令没问题(会话保持开放),去掉--daemon能运行但Capistrano任务卡着(前台进程占用会话)。
下面是几个经过验证的解决方案:
方案1:用nohup+输出重定向脱离会话
修改你的Sidekiq启动任务,用nohup忽略HUP信号,同时把标准输出和错误重定向到日志文件,让Sidekiq完全脱离Capistrano的会话:
namespace :sidekiq do desc "Start sidekiq" task :start do run "cd #{current_path} && bundle exec sidekiq --version" run <<-CMD cd #{current_path} && nohup bundle exec sidekiq --environment production --daemon --config config/sidekiq.yml >> logs/sidekiq.log 2>&1 && echo OK CMD end end
这样修改后,Sidekiq daemon会在Capistrano会话关闭后继续运行,日志也会正常写入sidekiq.log。
方案2:使用官方sidekiq-capistrano插件(最省心)
Sidekiq官方提供了针对Capistrano v2的集成插件,它已经处理了daemon化、会话脱离、进程管理等细节,不用自己写任务:
- 在Gemfile中添加对应版本的插件(适配你的Sidekiq 5.0.5):
gem 'sidekiq-capistrano', '~> 0.5.4'
- 在
deploy.rb中加载插件:
require 'sidekiq/capistrano'
- 之后直接使用官方提供的任务即可:
cap sidekiq:start cap sidekiq:stop cap sidekiq:restart
这个方案是最推荐的,因为官方插件会处理各种边缘情况,比如进程检查、日志管理等。
方案3:用setsid创建独立会话
另一种方式是用setsid命令让Sidekiq在新的会话组中运行,彻底脱离Capistrano的SSH会话:
namespace :sidekiq do desc "Start sidekiq" task :start do run "cd #{current_path} && bundle exec sidekiq --version" run "cd #{current_path} && setsid bundle exec sidekiq --environment production --daemon --config config/sidekiq.yml && echo OK" end end
setsid会为Sidekiq创建一个新的会话和进程组,这样Capistrano关闭原会话时不会影响到它。
验证步骤
执行完任务后,你可以通过以下方式确认问题解决:
- 检查
tmp/pids/sidekiq.pid对应的进程是否存在:ps aux | grep sidekiq - 查看
logs/sidekiq.log是否有正常的启动日志(比如Running in ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]这类内容)
内容的提问来源于stack exchange,提问作者pragmatic_programmer
相关产品推荐
相关产品推荐

