ZBLOG

on-failure的含义

好的,这是一个非常关键的概念。在 systemdRestart= 指令中,on-failure 是最常用的配置值之一。

on-failure 的含义

简单来说,Restart=on-failure 表示:仅在服务进程“异常失败”时,systemd 才会自动重启它。

这里的“异常失败”具体指的是以下几种情况:

  1. 进程以非零退出状态码退出 (Non-zero exit code):

    • 这是最常见的情况。在 Unix/Linux 惯例中,退出码为 0 表示成功,任何非零值(如 1, 127, 255 等)都表示某种错误或失败。
    • 举例:你的服务程序遇到了致命错误,调用 exit(1) 退出了。
  2. 进程由于信号而终止 (Terminated by a signal):

    • 进程被某个信号(Signal)强制杀死,但这个信号不是由 systemd 本身在正常停止或重启服务时发出的。
    • 典型例子:段错误 (Segmentation fault) 会触发 SIGSEGV 信号,导致进程终止。这种情况下 systemd 会重启服务。
    • 反例:当你运行 systemctl stop your-service.service 时,systemd 会发送 SIGTERM(或配置的 KillSignal)来优雅地停止服务。在这种情况下,即使进程被信号终止,也不会触发重启,因为这是预期的正常行为。
  3. 进程操作超时 (Operation timeout):

    • 如果为服务配置了 TimeoutStartSec=TimeoutStopSec=,并且在规定时间内启动或停止没有完成,systemd 会强制终止进程。这种因超时而导致的终止也会触发 on-failure 重启。
  4. 进程的守护进程初始化失败 (Watchdog failure):

    • 这是一个更高级的场景。如果配置了硬件看门狗 (WatchdogSec=),并且服务没有按时“报平安”,systemd 会认为服务挂起并将其终止,然后触发重启。

on-failure 与其它选项的对比

为了更好地理解它,可以看看其他常用的 Restart= 选项:

选项值 含义 适用场景
no 永不自动重启 简单的、运行一次就结束的任务,或者需要人工介入处理的故障。
on-success 仅在成功退出后重启(即退出码为 0)。 极其罕见。通常用于需要循环执行但每次都必须成功才继续的任务。
on-failure 仅在异常失败时重启(非零退出码、意外信号等)。 最常用。适用于需要持续运行的后台守护进程(daemons)。
on-abnormal 仅在因信号或超时等“异常”情况终止时重启。(比 on-failure 范围窄) 较少使用,用于区分正常退出和异常退出的场景。
on-watchdog 仅在看门狗超时时重启 高级用途,用于配置了硬件看门狗的服务。
always 无条件总是重启。无论进程如何退出(即使是正常停止),systemd都会重启它。 Docker容器、某些必须保证“永远在线”的激进策略。使用时需谨慎,因为用 systemctl stop 可能无法停止服务(需要配合 KillMode=mixed等)。

.service文件配置示例

[Unit]
Description=My Awesome Service

[Service]
Type=simple
ExecStart=/usr/bin/my-awesome-service
# Restart策略:在失败时重启
Restart=on-failure
# 如果连续启动太快,等待10秒再尝试重启
RestartSec=10s
# “异常失败”的判断条件:在60秒内最多允许重启5次
StartLimitIntervalSec=60
StartLimitBurst=5

[Install]
WantedBy=multi-user.target

⚠️重要提示:防止重启风暴

仅仅设置 Restart=on-failure 可能导致系统在服务有固有启动缺陷时陷入不断重启的循环(“重启风暴”)。因此,强烈建议同时配置以下两个参数来控制频率:

  • 
    StartLimitIntervalSec=<时长>
    
    设置一个时间窗口(例如 60s, 1min)。
  • 
    StartLimitBurst=<次数>
    
    在上述时间窗口内允许的最大启动次数。

如果在一分钟内 restarting超过了这个限制次数, systemd将不再尝试重新启动该单元,并会把该单元置入failed状态.

###总结

总而言之,

  • on success: exit code ==0 && exit signal is not one of the following: SIGHUP, SIGINT, SIGTERM, SIGPIPE, and also not be an unclean exit as result of a timeout or watchdog.
  • on failure: exit code !=0 || exit signal is one of the following: SIGHUP, SIGINT, SIGTERM, SIGPIPE, and also be an unclean exit as result of a timeout or watchdog.
  • on abnormal: exit signal is one of the following: SIGHUP, SIGINT, SIGTERM, SIGPIPE, and also be an unclean exit as result of a timeout or watchdog.
  • on abort: only when the service process exits withSIGABRT or due to an uncaught critical exception that triggers such behaviour.

所以对于你的问题来说:

  • ExecStartPost脚本执行失败(以非0状态码退出),会被视为一种failure.如果主服务的Restart=设置为包含这种情况(例如设置为always),那么主服务可能会被标记为失败并被尝试restart.
  • ExecStartPost脚本卡住无法退出(不返回),这会导致整个service startup过程超时(如果设置了TimeoutStartSec).这种超时属于一种unclean exit/abnormal termination.同样根据主服务的Restart策略来决定是否要restart.

所以答案是:取决于主服务的 Restart=和SuccessExitStatus等参数的配置.默认情况下(Restart=no),不会自动restart;但如果明确配置了比如 Restart=on-failure/always ,那么这两种情况都可能触发auto-restart.


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24284

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?