我有这个 runit 服务run
并且log/run
脚本正常运行。
事实上,服务本身可能会因外部原因而崩溃,并且可能在几分钟内无法启动。runit 处理这种情况的默认方式是每隔几秒钟重新启动服务。我该如何改变这种行为?
我最后的想法是添加一个check
脚本并在那里做一些魔术,但它似乎比它应该的要复杂得多。有没有更好更简单的方法?
答案1
我不熟悉此功能,但是,如果我的任务是解决这个问题,并且非常简短的手册页阅读没有提供一个简单的旋钮来调整这种行为,我会执行以下操作:
要么扩展现有的服务启动脚本,要么如果这很麻烦,在链中插入一个新的启动脚本(反过来启动原始启动脚本)。新的启动脚本不会立即启动服务,而是应该检查上次启动是否发生得足够近。这可以通过检查上次启动创建的信令文件来完成。如果该文件不存在,脚本可以继续接触该文件并启动服务。如果该文件存在,脚本应该检查该文件是否足够旧。如果它不够旧,它应该循环等待(休眠)直到文件足够旧。
类似这样的方法可能会有效(重新启动之间至少等待 1 分钟):
#!/bin/bash
SIGNALDIR=/tmp
SIGNALFILE=service.started
while /bin/true; do
found=`find "${SIGNALDIR}" -maxdepth 1 -name "${SIGNALFILE}" -mmin -1 | wc -l`
[ "${found}" -eq 0 ] && break
echo "Waiting"
sleep 10
done
touch "${SIGNALDIR}/${SIGNALFILE}"
original service start...
答案2
您应该在文件中限制./finish
该服务的重新启动速率,该文件在异常终止时运行。脚本./finish
将接收返回代码./run
,然后您可以确定要做什么等。就此而言,您应该让./finish
脚本大声尖叫故障并发送通知并跳到火上浇油...
答案3
我真的不喜欢基于 init 的进程管理(而 runit 基本上是 init 的替代品)。正如您所发现的,在进程死掉后立即重启失败进程并不是一个特别好的策略。我曾使用 init 来重启 monit,但仅此而已。(潜在的 OOM 杀手可能会杀死 monit)。
因此,我鼓励您寻找替代品,而不是修补。
Monit 已经很老了,但它的工作表现很好,而且我还没发现有更好的产品。它有一个很棒的特性,就是启动后不需要 malloc 更多内存,所以比用脚本语言编写的任何产品都要好。你最不希望看到的就是你的进程监视器因为无法获得内存而死掉。