如何编写bash脚本以便在进程死机时重新启动进程

问:

我有一个python脚本,它将检查队列并对每个元素执行操作:

# checkqueue.py
while True:
  check_queue()
  do_something()

我如何编写一个bash脚本来检查它是否正在运行,如果没有,则启动它。大致如下伪代码(或者它应该做一些类似 ps | grep 的事情?)

# keepalivescript.sh
if processidfile exists:
  if processid is running:
     exit, all ok

run checkqueue.py
write processid to processidfile
我将从crontab中调用它:
# crontab
*/5 * * * * /path/to/keepalivescript.sh

答:

避免使用 PID 文件、cron 或其他任何试图评估不属于其子进程的进程。

在UNIX中,有充分的理由只能等待子进程。任何试图解决这个问题的方法(ps解析、pgrep、存储PID等)都是有缺陷的,其中存在漏洞。待后文分析。

假设你的进程名为procA,监控它的进程名为procB,则需要procB成为procA的父进程。因为只有启动你的进程的进程才能可靠地等待它结束。而这在Bash中很容易实现。

until procA; do
    echo "procA crashed with exit code $?. Restart..." >&2
    sleep 1
done

上面的bash代码在一个until循环中运行procA。第一行启动procA并等待它结束。当它结束时,until检查其退出状态。如果退出状态为0,则表示它正常结束(这意味着你要求它以某种方式关闭,并且它成功关闭了)。在这种情况下,我们不想重新启动它(我们只是要求它关闭!如果退出状态不是0,until将运行循环体,该循环体在STDERR上发出错误消息,并在 1 秒后重新启动循环(返回第 1 行)。

我们为什么要等一会儿?因为如果procA的启动顺序出了问题并立即崩溃,你将得到一个非常密集的循环,不断重新启动和崩溃。sleep 1消除了这种压力。

然后需要做的就是启动这个bash脚本,它将监控procA并在必要时重新启动它。如果你想在(操作系统)启动时启动监控脚本,你可以用@reboot规则在用户的 cron(1) 中调度它。使用crontab -e命令打开你的cron规则,然后添加一个规则来启动你的监控脚本:

@reboot /usr/local/bin/procAmonitor

至于不使用PID文件的理由:
1. PID重用(可能导致杀死错误的进程)。
2. PID文件过时。你需要过于更复杂的逻辑来检查PID文件是否过时,而任何这样的逻辑都同样有1中的缺陷。
3. 如果你甚至没有写访问权限或者处于只读环境中该怎么办?

或者,查看systemd.unit(5)。你可以在/lib/systemd/system目录中添加一个名为procA.service的配置文件,让systemd进程监控你的procA。

[Unit]
Description=Daemon for procA.

[Service]
ExecStart=/path/to/procA
Restart=on-failure
RestartSec=1s

[Install]
WantedBy=multi-user.target
然后再执行以下命令即可:
systemctl daemon-reload
systemctl enable procA.service

参考:

  • stackoverflow question 696839
  • man systemd.unit
  • man systemctl

PS:

本文首发于公众号: 程序熵, 更多有用文章请点击关注 code-shang

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值