ubuntu 上的 sidekiq 无法通过 upstart 停止

ubuntu 上的 sidekiq 无法通过 upstart 停止

我为 sidekiq 安装了 upstart 服务,如下所示在 wiki 中有说明

也就是说,我有一个 upstart 脚本,它创建了以下进程:

# skipped other insstructions
script
exec /bin/bash <<'EOT'
  source /home/me/.my_env
  cd /home/me
  exec bin/sidekiq -e production
EOT
end script

服务完美启动,但正如我们所见,sidekiq 的 PID 不等于已知的 PID upstart

» initctl status sidekiq
# sidekiq start/running, process 16020
» ps axww|grep sidekiq
# 16181 ?        Sl     0:41 sidekiq 3.0.0 me[0 of 3 busy]

该配置适用于除 sidekiq 之外的任何其他 upstart 脚本:

» sudo initctl stop sidekiq
# sidekiq stop/waiting
» ps axww|grep sidekiq
# 16181 ?        Sl     0:45 sidekiq 3.0.0 me[0 of 3 busy]

似乎initctl终止了 bash 进程,它将其视为作业(16020),但底层sidekiq仍然存在:

» ps axww|grep  '16181\|16020'
# 16181 ?        Sl     0:45 sidekiq 3.0.0 me[0 of 3 busy]

我究竟做错了什么?

答案1

听起来 sidekiq 正在去中心化,或者至少是分叉。所以你需要关注http://upstart.ubuntu.com/cookbook/#expect,要么找到一个以非守护进程模式运行的 sidekiq 选项,要么添加一个适当的 expect 语句。

答案2

感谢@douglas-leeder 为我指明正确的方向。

sidekiq既不会妖魔化自己也不会分叉自身(除非-d明确指定选项。)但在我的 exec 脚本中,我调用了其他进程,upstart 试图将其算作我的一般进程。

expect选项在这里没有帮助,因为实际的 sidekiq 进程在链中排在第 6 位。更糟糕的是:指定expect fork会导致 upstart 在停止服务时挂断,而指定会导致expect daemon在启动服务时挂断。请参阅此回答如何解决 sidekiq 挂断问题。

我最终坚持的解决方案是:需要定义一段post-stopupstart 脚本,其中包含以下内容:

post-stop script
   # ps-grep your PIDS
   # for sidekiq:
   SQ_PIDS=`ps -Ao pid,command | grep sidekiq | grep -v grep | awk '{ print $1 }' | sed 'N;s/\n/ /g'`
   sudo kill -USR1 $SQ_PIDS
   sleep 3
   sudo kill -9 $SQ_PIDS
   sudo rm sidekiq.pid 2>&1 >/dev/null
end script

上述代码将尝试正常关闭 sidekiq 并将其终止。这不是最优雅的解决方案,但它确实有效。

相关内容