Linux systemd 服务异常退出后怎样自动重启
来源:17golang原创
时间:2026-10-18 14:47:01 355浏览 收藏
如果 Linux 上的常驻服务异常退出,systemd 通常应该使用 Restart=on-failure 自动尝试恢复,再用 RestartSec 拉开两次启动的间隔。这个选择比 Restart=always 更容易保留“正常结束”和“真正故障”的区别;如果服务只想在信号或超时等异常情况下重启,则可以考虑 on-abnormal。
官方文档:https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
- 常驻 worker 发生非零退出、异常信号或超时,通常选择
Restart=on-failure。 - 管理员执行
systemctl stop不应被当成故障,systemd 不会因此自动拉起服务。 - 连续失败时先看
Result、ExecMainStatus和NRestarts,不要只把重启次数调大。
先分清异常退出和主动停止
systemd 的重启判断看的是服务进程怎样结束:退出码、信号、启动或停止操作超时,以及 watchdog 等状态都会参与判断。对于长期运行的服务,on-failure 会覆盖非零退出和异常信号,也会覆盖相关超时;但由 systemd 自己执行的停止或重启,不会再次触发自动重启。
这一区分很重要。发布脚本执行 systemctl restart 时,期望的是一次明确的运维动作;程序崩溃时,才需要让 unit 尝试恢复。如果把两者混成“只要进程没了就永远拉起”,服务就很难被安全停机。
按场景比较三种 Restart 策略
我在配置常驻服务时,通常先把需求归到下面三类,再决定参数,而不是一上来就用 always。它们的差别不在于“能不能重启”,而在于哪些退出被认为值得重试。
| 场景 | 优先选择 | 适合的原因 |
|---|---|---|
| 常驻服务,非零退出通常表示故障 | on-failure | 能恢复异常退出,同时保留正常退出语义 |
| 允许服务主动结束,只兜底信号和超时 | on-abnormal | 不会因为普通成功退出而重新拉起 |
| 任何结束都必须再次启动 | always | 适合确实需要无条件常驻的服务,但会掩盖退出原因 |
如果服务是一次性任务,不能因为看到了“自动重启”就套用常驻进程策略。尤其是 Type=oneshot,成功退出和 always、on-success 还有额外限制;这时应先确认 unit 的生命周期,再决定是否需要重启。

用等待间隔和启动限流防止重启风暴
只写 Restart=on-failure 还不够。服务如果每次启动都立刻失败,systemd 会反复尝试,日志和依赖服务都会被拖入噪声。可以把等待时间和窗口内的启动次数一起写进 unit:
[Unit]
Description=Demo worker service
After=network-online.target
Wants=network-online.target
# 60 秒窗口内最多允许 5 次启动尝试,避免持续崩溃形成风暴
StartLimitIntervalSec=60s
StartLimitBurst=5
[Service]
Type=exec
ExecStart=/usr/local/bin/demo-worker
# 只对失败退出自动重启,正常退出仍保留为正常结果
Restart=on-failure
# 给依赖恢复和日志落盘留出时间
RestartSec=5s
[Install]
WantedBy=multi-user.target
RestartSec 控制一次自动重启前的等待;StartLimitIntervalSec 和 StartLimitBurst 则是启动速率保护。达到限制后,问题就从“要不要重启”变成了“为什么一直启动失败”,不应简单地把 Burst 调得很大。
复查服务状态,而不是只看 active
修改 unit 后,先重新读取配置,再观察退出原因、重启次数和日志。下面的命令只展示复查路径,输出内容会随服务本身和部署环境变化。
# 让 systemd 重新读取 unit 文件
sudo systemctl daemon-reload
# 启用并立即启动服务
sudo systemctl enable --now demo-worker.service
# 查看当前状态、最近一次结果和退出状态
systemctl status demo-worker.service --no-pager
# 读取适合排障的结构化字段
systemctl show demo-worker.service \
-p ActiveState -p SubState -p Result \
-p ExecMainCode -p ExecMainStatus -p NRestarts
# 查看当前启动周期内的服务日志
journalctl -u demo-worker.service -b --no-pager -n 80
如果 Result=exit-code,继续对照 ExecMainStatus 判断应用返回了什么;如果是 Result=start-limit-hit,说明 unit 已触发启动限流,应该回到日志和依赖上找根因。修复后可以执行下面的清理动作,再重新启动:
# 修复配置或依赖后清理 unit 的失败状态
sudo systemctl reset-failed demo-worker.service
# 重新发起一次启动,观察是否还会连续失败
sudo systemctl start demo-worker.service

几个容易误判的边界
写了 on-failure 还是不重启? 先检查服务是否以 systemd 认为“成功”的方式结束、是否命中了 RestartPreventExitStatus=,以及是否已经触发启动速率限制。不要先把策略改成 always。
什么时候使用 on-abnormal? 当程序有明确的正常退出路径,而你只希望对异常信号、超时或 watchdog 做恢复时,它比 on-failure 更贴近语义。
退出码能不能参与重启决策? 可以。对于代表“配置不可用、继续重试没有意义”的退出码,可以配合 RestartPreventExitStatus= 停止无效循环;但这需要应用和运维先约定退出码含义。
常见问题
systemctl stop 后服务为什么没有自动启动?
这是预期行为。systemd 主动执行的停止操作不属于需要自动恢复的进程故障,否则管理员将无法可靠停机。
on-failure 和 always 怎么选?
长期运行服务通常先用 on-failure;只有确实要求任何退出都重新启动时才用 always。如果服务允许正常结束但要兜底异常信号和超时,可以考虑 on-abnormal。
-
Golang · Go教程 | 4个月前 | 超时控制 · 故障排查 · Go教程 · 后端工程 · Golang实战 · HTTP客户端 · golang Go 性能优化 net/http context Transport 超时 http.Client 生产实践205 收藏
-
Golang · Go教程 | 3个月前 | 并发 · HTTP · 性能优化 · 故障排查 · Go教程 · Go Goroutine 连接复用 pprof http.Client close Response.Body201 收藏
-
Golang · Go教程 | 2个月前 | golang · JSON · 故障排查 · Go教程 · 接口设计 · JSON Go 接口兼容性 DisallowUnknownFields 严格解码174 收藏
-
423 收藏
-
Golang · Go教程 | 1个月前 | golang · 服务端 · 故障排查 · net/http · 连接泄漏 StateIdle ConnState Go net/http StateHijacked311 收藏
-
353 收藏
-
210 收藏
-
318 收藏
-
403 收藏
-
294 收藏
-
213 收藏
-
101 收藏
-
259 收藏
-
427 收藏
-
363 收藏
-
280 收藏
-
144 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习