You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:18:03