systemd service Restart=always 为什么导致失败循环
把 Restart=always 写进 service 后,进程一退出就被再次拉起;如果程序本身每次启动都立刻失败,就会看到“启动—退出—再启动”的循环。它并不代表 systemd 能修复应用的根因。更准确的理解是:Restart=always 决定“退出后是否尝试重启”,RestartSec= 决定“隔多久再试”,而 StartLimitIntervalSec= 与 StartLimitBurst= 决定“时间窗口内最多允许多少次启动”。
官方资料:https://github.com/systemd/systemd/blob/main/man/systemd.service.xml
- 先看
Result、ExecMainStatus和 journal,再改 Restart 参数。 - 长期运行的守护进程通常优先用
Restart=on-failure,避免正常退出也被拉起。 - 启动限流触发后,必须修复真实退出原因,再用
reset-failed和一次受控启动复查。
出现这类循环的核心原因大多是进程自身启动时就触发了前置错误,加上 systemd 的重启策略没加边界限制,每次刚拉起立刻报错退出,被规则再次触发重启,最终形成无限失败重启的闭环。
先分清 Restart=always 和启动限流各管什么
systemd 把服务重启拆成两个判断。服务进程退出、被信号终止或启动超时后,Restart=always 会把它纳入自动重启;但每次重启仍然是一次新的启动尝试,受到 unit 的启动速率限制。于是,一个立即退出的二进制会快速消耗启动次数,最后出现 Start request repeated too quickly,服务进入失败状态。
这也是为什么单纯把 Restart=always 改得更“强”通常没有用:它只会让 systemd 更积极地重复同一个错误。建议先把等待时间和上限写清楚:
[Unit] Description=Example worker service # 只描述启动顺序;依赖失败仍要回到对应日志定位 After=network-online.target Wants=network-online.target StartLimitIntervalSec=60s StartLimitBurst=3 [Service] Type=simple ExecStart=/opt/example/bin/worker --config /etc/example/worker.yaml # 守护进程异常退出时重启,正常退出不强行拉起 Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target
StartLimitIntervalSec 和 StartLimitBurst 放在 [Unit];Restart 和 RestartSec 放在 [Service]。如果这个程序是一次性任务,正常退出本来就是成功结果,不应拿 Restart=always 把它变成长驻服务。

用退出码和日志找到真正的失败原因
看到循环时不要先执行多次 restart 把现场冲掉。先保存状态与最近日志:
# 读取当前状态、主进程退出码和最近一段日志 sudo systemctl status example-worker.service --no-pager sudo systemctl show example-worker.service \ -p Result -p ExecMainCode -p ExecMainStatus -p NRestarts sudo journalctl -u example-worker.service -b -n 80 --no-pager
如果 Result=exit-code、ExecMainStatus=1,优先检查配置文件、工作目录、权限和环境变量;如果是 status=203/EXEC,重点看 ExecStart 路径、执行权限和解释器;如果日志只剩“repeated too quickly”,说明限流是结果,不是最初的根因。NRestarts 可以帮助确认是否真的发生了多次自动拉起。
| 证据 | 通常说明 | 下一步 |
|---|---|---|
ExecMainStatus=1 | 程序主动以非零码退出 | 看应用日志、配置和参数 |
203/EXEC | 执行文件或执行方式有问题 | 检查路径、权限、shebang |
Start request repeated too quickly | 启动速率限制已触发 | 先修复前两项,再复位失败状态 |

依赖关系会放大问题,但不会替代根因
After=network-online.target 只表达排序,不能保证网络服务已经满足应用的业务条件;Wants= 会在当前服务启动时顺带拉起目标,但目标失败不一定让本服务失败;Requires= 的失败影响更强,依赖停止时本服务也可能被停止。排查时应同时看依赖树:
# 查看 unit 的依赖与排序关系,避免把依赖链误认为重启根因 sudo systemctl list-dependencies example-worker.service sudo systemctl cat example-worker.service sudo systemd-analyze verify /etc/systemd/system/example-worker.service
如果服务依赖了一个同样会失败的 unit,先修复被依赖方;如果配置里存在相互触发的 Wants= 或外部 watchdog,也要确认是谁真正发起了下一次启动。不要用增加 StartLimitBurst 来掩盖依赖链上的配置错误。
修改后怎样安全恢复并确认没有再循环
确认配置已保存后,先让 PID 1 重新读取 unit,再清掉“因限流留下的失败状态”,最后只启动一次:
# 重新载入 unit,清除失败标记,然后进行一次受控启动 sudo systemctl daemon-reload sudo systemctl reset-failed example-worker.service sudo systemctl start example-worker.service sudo systemctl status example-worker.service --no-pager sudo journalctl -u example-worker.service -b -n 40 --no-pager
成功标准不是“命令返回成功”这么简单,而是服务保持 active (running),NRestarts 不再持续增加,日志中没有新的退出与限流提示。如果程序确实会因临时依赖失败而退出,可以保留 Restart=on-failure,把 RestartSec 调到足以等待依赖恢复的值;不要无限放大限流窗口,让错误变成高频重启。
相关问题
Restart=always 和 Restart=on-failure 有什么区别?
always 连正常退出也会尝试重启;on-failure 主要针对非零退出、异常信号和超时。长时间运行的服务通常先选后者。
为什么 Restart=always 仍然不重启?
可能已触发启动速率限制,也可能是手动停止、条件判断未满足或 unit 根本没有成功进入可重启的服务状态。先看 journal 和 systemctl show,不要只看配置文件。
改完 service 文件为什么没有生效?
unit 文件变更需要 systemctl daemon-reload;它只重新载入配置,不等于已经启动新进程。之后再按需执行 reset-failed 和一次 start。
Go http.Server 如何配置优雅关闭的超时时间
- 上一篇
- Go http.Server 如何配置优雅关闭的超时时间
- 下一篇
- Go TLS 客户端只在生产环境报证书错误怎么办
-
- 文章 · linux | 4小时前 | Linux · Linux tmpfiles.d systemd-tmpfiles 临时目录清理
- Linux tmpfiles.d 临时目录清理规则的部署
- 223浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux vmstat 指标与 I/O 等待的判断
- 225浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux perf record 采样权限与调用栈配置
- 301浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux systemd.socket ListenDatagram 怎样监听 UDP 套接字
- 216浏览 收藏
-
- 文章 · linux | 4小时前 | linux运维 · Linux Rsync 断点续传 partial-dir append-verify
- Linux rsync 部分传输后的断点续传参数
- 108浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux tar 排除规则与目录层级的打包
- 434浏览 收藏
-
- 文章 · linux | 4小时前 | Linux ·
- Linux nftables 集合规则的批量维护
- 112浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux find 按时间与大小组合筛选文件
- 404浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux ip 命令查看策略路由命中顺序
- 118浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux systemd RestrictAddressFamilies 怎样限制服务使用的网络协议族
- 117浏览 收藏
-
- 文章 · linux | 4小时前 |
- Linux systemd-escape 怎样把路径转换成实例化 unit 名称
- 382浏览 收藏
-
- 文章 · linux | 4小时前 | 定时器 · Linux · 运维 · 服务管理 · Linux 定时任务 OnCalendar 单调时间 systemd.timer OnBootSec
- Linux systemd.timer 日历与单调时间的选择
- 430浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 758次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 756次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 838次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 805次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 635次使用
-
- Linux vmstat 如何分辨内存抖动与磁盘等待:si、so、wa 与复测顺序
- 2026-08-30 501浏览
-
- Linux搭建vsftpdFTP服务器教程
- 2026-04-30 501浏览
-
- Shell脚本安装教程:.sh一键安装指南
- 2026-03-16 501浏览
-
- Linux清空文件内容的几种方法
- 2025-12-01 501浏览
-
- Linux命令行下载文件技巧
- 2025-11-23 501浏览

