在代码中,重新启动和停止/启动之间没有当前区别。在 supervisorctl 调用中重新启动:
self.do_stop(arg)
self.do_start(arg)
虽然有一些关于允许不同信号的讨论,但应用程序中没有“重启”状态。主管已经能够向进程发送不同的信号。 (允许更多地控制重新加载/重启是long standing "gap")
这意味着您至少有两个选择,但使这项工作成功的关键是该进程需要在 shutdown
时记录一些状态
选项 1. 最简单的选项是使用 supervisorctl signal <singal> <process> 而不是调用 supervisorctl restart <process> 并在某处记录发送的信号,以便在启动时读取最后一个信号。
选项 2。 然而,更有趣的解决方案是不要期望任何上游更改,即继续允许使用重新启动并区分停止、崩溃和重新启动
在这种情况下,启动和重新启动之间唯一不同的信息是重新启动应该在旧进程关闭和新进程启动之间的时间要短得多过程。因此,如果在关机时记录了时间戳,那么在启动时,现在和上次关机之间的差异将区分启动和重启
为此,我有一个类似你的定义,但定义了停止信号:
[program:long_script]
command=/usr/local/bin/long.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/long.err.log
stdout_logfile=/var/log/long.out.log
stopsignal=SIGUSR1
通过将来自 supervisord 的停止设为特定信号,您可以区分崩溃和正常停止事件,并且不会干扰正常的终止或中断信号
然后作为 bash 脚本的第一行,我为这个信号设置了一个陷阱:
trap "mkdir -p /var/run/long/; date +%s > /var/run/long/last.stop; exit 0" SIGUSR1
这意味着每次我们从 supervisord 发送停止时,作为纪元的日期将记录在文件 /var/run/long/last.stop 中
然后作为脚本中的下一行,计算最后一站和现在之间的差异
stopdiff=0
if [ -e /var/run/long/last.stop ]; then
curtime=$(date +%s)
stoptime=$(cat /var/run/long/last.stop | grep "[0-9]*")
if [ -n "${stoptime}" ]; then
stopdiff=$[ ${curtime} - ${stoptime} ]
fi
else
stopdiff=9999
fi
stopdiff 现在将包含停止和启动之间的秒数差异,如果停止文件不存在,则为 9999。
这可以用来决定做什么:
if [ ${stopdiff} -gt 2 ]; then
echo "Start detected (${stopdiff} sec difference)"
elif [ ${stopdiff} -ge 0 ]; then
echo "Restart detected (${stopdiff} sec difference)"
else
echo "Error detected (${stopdiff} sec difference)"
fi
您必须选择从发送停止到实际开始脚本实际需要多长时间:这里,我只允许 2 秒,任何更长的时间都被视为“开始”。如果需要以特定方式关闭脚本,则需要在陷阱语句中增加一点复杂性(而不仅仅是exit 0
由于崩溃不应在停止文件中记录任何时间戳,因此如果您还定期在某处记录运行时间戳,您应该能够判断出由于崩溃而正在发生启动。