为什么新贵继续重生我的过程?

我编写了一个upstart脚本来在tmux会话中启动一个守护进程。 如果它意外死亡,它运作良好并重新生成过程,但我似乎无法手动停止它。

这项工作(称为bukkit)如下所示:

start on filesystem stop on runlevel [!2345] respawn respawn limit 5 30 chdir /home/minecraft/bukkit expect daemon kill timeout 30 pre-start script test -x /home/minecraft/bukkit/craftbukkit-0.0.1-SNAPSHOT.jar || { stop; exit 0; } end script pre-stop script tmux send -t bukkit "stop" tmux send -t bukkit "Enter" sleep 10 # Wait for server to shut down properly end script exec tmux new-session -d -s minecraft -n bukkit "sudo -u minecraft -- /home/minecraft/java/jre1.6.0_27/bin/java -Xincgc -Xmx1G -jar /home/minecraft/bukkit/craftbukkit-0.0.1-SNAPSHOT.jar" 

当我发出一个stop bukkit它会冻结~10秒(睡眠计时器,我猜)并打印bukkit start/running, process 2391 。 当我设置upstart进行调试时,我在日志中找到了这些相关的行:

 Sep 21 19:14:59 cheftest init: bukkit goal changed from start to stop Sep 21 19:14:59 cheftest init: bukkit main process (2499) exited normally Sep 21 19:14:59 cheftest init: bukkit main process ended, respawning Sep 21 19:14:59 cheftest init: bukkit goal changed from stop to respawn 

为什么新手应该停止重复我的进程呢?

这里的难点在于’respawn’与预停止脚本的组合,该脚本告诉进程停止。 从init(5):

  respawn A service or task with this stanza will be automatically started if it should stop abnormally. All reasons for a service stopping, except the stop(8) command itself, are considered abnormal. Tasks may exit with a zero exit status to prevent being respawned. 

文档有点不清楚是否退出状态是否会导致重新生成。 但是,从根本上说,你已经发现了一个暴发户的错误,因为当目标是“停止”时,主要过程结束不应该导致对’respawn’的更改。

要解决这个bug,你应该能够使用“正常退出”来告诉upstart这是一种正常的方法来停止工作并且它不应该重生。

  normal exit STATUS|SIGNAL... Additional exit statuses or even signals may be added, if the job process terminates with any of these it will not be considered to have failed and will not be respawned. normal exit 0 1 TERM HUP 

请注意,通常情况下,使用信号(在必要时指定“kill signal N”)而不是使用发出命令的预停止进程来终止进程会更加健壮; 但是,如果服务在收到信号时不支持干净关机,那么当然并不总是这样。

如果其他人在这里结束,我已经提交了一个有效的补丁:

https://bugs.launchpad.net/upstart/+bug/568288/comments/6

为此,在新贵1.10中发布了一个修复程序,所以现在不应该发生。