Systemd配置OnFailure在程序返回错误码时未触发问题咨询
systemd 服务每次异常退出触发故障处理逻辑解决方案
问题根因
systemd 原生的OnFailure=触发规则为仅当服务彻底进入最终失败状态(不再尝试重启)时才会执行依赖。你配置了Restart=on-failure后,只要重启次数未达到StartLimitBurst阈值,服务就会被标记为重启中而非最终失败,因此不会触发OnFailure配置的处理服务。
路径错误场景下触发是因为服务短时间内反复启动失败,触发了Start request repeated too quickly的限制,服务进入最终失败状态,才触发了OnFailure。
可行实现方案
方案1:使用ExecStopPost钩子(推荐,同时满足自动重启+每次异常触发处理逻辑需求)
ExecStopPost是systemd提供的生命周期钩子,无论服务是正常退出还是异常退出都会执行,你可以在钩子中判断服务退出状态,仅异常时调用你的故障处理服务,不影响原有自动重启逻辑。
修改后的服务配置如下:
[Unit] Description=Demo unit Wants=multi-user.target [Service] ExecStart=/bin/bash /home/root/demo.sh Restart=on-failure RestartSec=1 Type=simple # 新增故障触发逻辑 ExecStopPost=/bin/bash -c 'if [ "$SERVICE_EXIT_STATUS" -ne 0 ]; then /bin/systemctl start FailHandler@%N.service; fi'
说明:$SERVICE_EXIT_STATUS是systemd传递给ExecStopPost的内置环境变量,值为服务主进程的退出码,非0即代表异常退出。
方案2:调整启动限制参数(仅适配原生OnFailure逻辑,不推荐)
如果你必须使用原生OnFailure触发规则,可以把启动限制阈值设为1,每次异常退出直接标记为最终失败触发处理逻辑:
[Unit] Description=Demo unit Wants=multi-user.target OnFailure=FailHandler@%N.service # 新增启动限制配置 StartLimitBurst=1 StartLimitIntervalSec=10s [Service] ExecStart=/bin/bash /home/root/demo.sh Restart=on-failure RestartSec=1 Type=simple
注意:该方案触发OnFailure后服务会停止自动重启,不符合你要求的崩溃自动重启的需求,仅做原理参考。
配套注意事项
- 建议将
FailHandler@.service配置为Type=oneshot,确保故障处理逻辑执行完整 - 若需要传递更多故障信息(如退出码、进程PID、崩溃时间等)到处理逻辑,可以在
ExecStopPost中先将信息写入临时文件,再由故障处理服务读取使用
内容的提问来源于stack exchange,提问作者Sarge324
相关产品推荐
相关产品推荐

