You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Upstart作业依赖配置异常:job1恢复后job3无法重启的解决方案咨询

Upstart多作业依赖自动恢复问题的解决方案

刚好碰到过类似的Upstart作业依赖坑,我来给你捋清楚问题和解决办法:

问题还原

你现在有三个Upstart作业:job1job2job3,其中job3的配置是这样的:

start on (started job1 and started job2)
stop on (stopping job1 or stopping job2)

目前的运行情况是:

  • 系统启动时,job3能正常跟着job1job2一起启动,没问题
  • 但如果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自然不会自己启动

可行的解决办法

我们可以在job1job2的启动后脚本里,主动检查另一个依赖作业的状态,如果对方已经在运行,就手动启动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的事件驱动设计,也可以自定义一个事件:

  1. job3start on改成:
    start on (started job1 and started job2) or job3-deps-ready
    
  2. 然后在job1job2post-start脚本里,换成触发自定义事件:
    initctl emit job3-deps-ready
    

这样做的好处是不用直接操作job3的启动命令,更符合Upstart的设计逻辑,不过直接启动job3的方式更直观,适合快速解决问题。

内容的提问来源于stack exchange,提问作者jouge

火山引擎 最新活动