我正在使用 Monit 来监控需要启动和运行的各种进程作为一个团队网站正常运行所需的所有依赖项。要启动或关闭网站,必须按照明确的顺序启动或停止进程。依赖项如下。(名称已更改以保护无辜者。我在实际配置中使用了更具描述性的名称。)
该服务
site
依赖于site.workerA
、site.workerB
和site-redis
。两名工人都依赖
site-redis
。
站点总是通过 Monit 启动或停止,以避免出现竞争条件或 Monit 与我作对的可能性。(例如,我停止一项服务,但 Monit 会不断将其重新启动。)
问题是启动整个网站需要的时间比必要的时间要多得多。如果我指示 Monit 启动网站,那么一旦 Monit 确定了依赖关系,Monit 的操作顺序如下:
- 开始
site-redis
。 - 睡眠2分钟。
- 检测到正在
site-redis
运行,因此启动两个工作程序。 - 睡眠2分钟。
- 检测到workers和redis正在运行,因此启动
site
。 - [睡眠2分钟]
- [检测到
site
正在运行。]
我把最后两个步骤括起来了,因为它们实际上是没有意义的,因为该网站在最后 2 分钟间隔之前就已经有效启动并运行了。
2 分钟的休眠是 Monit 检查服务时使用的默认轮询间隔。我知道我可以减少此间隔,以便这些服务总是更频繁地轮询。例如,我可以这样做
check process site.workerB pidfile "/srv/site/var/run/site/site.workerB.pid"
every [number] cycles
...
我还必须将轮询周期的长度改为更短的值,以使周期少于 2 分钟。
但是,我不希望 Monit总是更频繁地轮询这些服务。我希望 Monit 仅在等待状态改变时更频繁地轮询服务。假设,如果 Monit 已启动一项服务并且另一项服务依赖于它,则以 5 秒的间隔而不是 2 分钟进行轮询。
我没有看到任何方法来配置 Monit 来执行此操作,但也许我错过了什么。
以下是我上面散文描述的说明。删除与问题无关的内容后,Monit 配置如下:
check process site-redis pidfile ".../site/redis.pid"
group site
start program = ...
stop program = ...
if does not exist then start
check process site pidfile ".../site/site.pid"
group site
depends on site.workerA, site.workerB, site-redis
start program = ...
stop program = ...
if does not exist then start
check process site.workerA pidfile ".../site/site.workerA.pid"
group site
depends on site-redis
start program = ...
stop program = ...
if does not exist then start
check process site.workerB pidfile ".../site/site.workerB.pid"
group site
depends on site-redis
start program = ...
stop program = ...
if does not exist then start
答案1
你实际上可以通过以下方式触发对 monit 的重新评估monit validate
或者SIGUSR1
。
因此,您可以将启动/停止程序重写为:
#!/bin/bash
function background {
i="0"
while [ $i -lt 20 ]; do
monit validate > /dev/null
monit status __YOUR__SERVICE__NAME__HERE__ | grep OK > /dev/null && exit 0
sleep 5
i=$[$i+1]
done
}
# restart procedure
state=$?
background &
exit $state
长话短说:重启过程完成后,其退出代码会被跟踪,并启动后台循环。它运行 20 次,每次运行后休眠 5 秒(约 1 分 40 秒)。它强制 monit 重新评估其状态,如果状态为,则跳出循环OK
。如果不是,则循环继续。最后,脚本本身以重启过程退出代码退出。