Upstart作业依赖配置异常:job1恢复后job3无法重启的解决方案咨询
Upstart多作业依赖自动恢复问题的解决方案
刚好碰到过类似的Upstart作业依赖坑,我来给你捋清楚问题和解决办法:
问题还原
你现在有三个Upstart作业:job1、job2、job3,其中job3的配置是这样的:
start on (started job1 and started job2) stop on (stopping job1 or stopping job2)
目前的运行情况是:
- 系统启动时,
job3能正常跟着job1、job2一起启动,没问题 - 但如果
job1(或者job2)故障停止,job3会跟着停掉——这符合预期 - 头疼的是:当故障的作业(比如
job1)恢复运行后,job3不会自动启动,得手动去启动它
为啥会这样?
这是Upstart的核心机制决定的:它是事件驱动,不是状态检查的初始化系统。
- 系统启动时,
job1启动触发started job1事件,job2启动触发started job2事件,两个事件同时满足,job3就启动了 - 当
job1故障停止,触发stopping job1事件,满足stop on的条件,job3就停了 - 但
job1恢复时,只会触发一次started job1事件,而job2本来就处于运行状态,没有新的started job2事件触发,所以start on (started job1 and started job2)的条件没法再次满足,job3自然不会自己启动
可行的解决办法
我们可以在job1和job2的启动后脚本里,主动检查另一个依赖作业的状态,如果对方已经在运行,就手动启动job3。
给job1加启动后检查
修改job1的配置文件,添加post-start脚本:
post-start script # 检查job2是否处于运行状态 if status job2 | grep -q "start/running"; then # 如果job2在跑,直接启动job3 initctl start job3 fi end script
给job2加启动后检查
同样,修改job2的配置文件,加上对应的post-start脚本:
post-start script # 检查job1是否处于运行状态 if status job1 | grep -q "start/running"; then initctl start job3 fi end script
额外小技巧
如果你想更贴合Upstart的事件驱动设计,也可以自定义一个事件:
- 把
job3的start on改成:start on (started job1 and started job2) or job3-deps-ready - 然后在
job1和job2的post-start脚本里,换成触发自定义事件:initctl emit job3-deps-ready
这样做的好处是不用直接操作job3的启动命令,更符合Upstart的设计逻辑,不过直接启动job3的方式更直观,适合快速解决问题。
内容的提问来源于stack exchange,提问作者jouge




