当前位置:首页 > 文章列表 > 文章 > linux > Linux systemd Restart=on-failure 为何不重启手动停止服务

Linux systemd Restart=on-failure 为何不重启手动停止服务

来源:17golang原创 2026-09-10 14:58:53 0浏览 收藏

给服务写了 Restart=on-failure,然后执行 systemctl stop demo.service,发现它没有自己回来,这是正常行为。这个配置关注的是服务异常退出、被异常信号终止或操作超时;如果停止动作本身是 systemd 按管理员请求执行的,systemd 会把它当作有意停止,不再创建自动重启。

官方资料:https://www.freedesktop.org/software/systemd/

先判断“谁让服务停下来的”:如果是 systemctl stop、依赖事务或系统关机,优先按人工控制处理;如果是进程非零退出、崩溃、超时或 watchdog 失败,Restart=on-failure 才可能介入。想恢复手动停止的服务,应明确执行 systemctl startsystemctl restart

要点速览
  • Restart=on-failure 不会覆盖 systemctl stop 这种明确的人工停止。
  • ResultExecMainCodeExecMainStatus 和日志时间线要一起看。
  • 自动恢复要配合 RestartSec 与启动限流,避免故障服务反复拉起。

为什么手动停止不会触发 Restart=on-failure

Restart= 判断的是服务进程结束的原因,不是“只要服务不在 active 就启动”。在 on-failure 模式下,非零退出、未被视为正常的信号、启动或停止超时,以及 watchdog 超时,都属于可能的恢复场景。

systemctl stop 是管理员提交给 systemd 的停止作业。systemd 会主动结束服务进程,并记录这次停止由管理器操作产生;如果随后仍按失败逻辑重启,管理员就无法可靠地维护停机窗口、发布窗口或故障隔离状态。因此,服务被 systemd 主动停止时,自动重启逻辑会被抑制。

Linux systemd中手动停止请求、停止作业、服务进程与Restart on failure判定边界的原创静态关系图
图1:手动停止属于 systemd 管理器的控制边界,Restart=on-failure 主要处理服务自身的失败结果。

异常退出与手动停止怎么区分

不要只看 ActiveState=inactive。它只能说明当前没有运行,不能说明为什么停止。排查时先看单元摘要,再把主进程退出字段与本次启动日志放到同一时间点比较:

# 查看当前状态、结果和主进程退出信息
systemctl show demo.service \
  -p ActiveState -p SubState -p Result \
  -p ExecMainCode -p ExecMainStatus

# 查看本次启动以来的服务日志,确认停止前最后一条原因
journalctl -u demo.service -b --no-pager -n 80

如果日志显示管理员执行了 stop,或状态变化与发布脚本、依赖事务同时发生,就不要把它归类为故障。若 Result=exit-code、主进程返回非零,或者日志出现崩溃与超时,则继续检查 ExecStart、环境变量、依赖服务和资源限制。

观察点更像手动停止更像故障退出
触发来源systemctl stop、关机或依赖事务进程自行退出、信号、超时或 watchdog
Result通常体现为正常停止结果可能是 exit-code、signal、timeout、watchdog
处理方式确认停机意图后 start/restart先查日志和根因,再观察自动恢复
Linux systemd通过Result、ExecMainStatus、ActiveState和journalctl区分手动停止与故障退出的原创关系图
图2:把状态字段、日志和启动限流放在同一排查面,才能避免只凭 inactive 误判。

服务单元怎样写才符合自动恢复预期

长时间运行的服务可以先从一个小而明确的单元开始。RestartSec 给失败后的再次启动留出缓冲,启动限流则防止配置错误导致快速重启循环:

[Unit]
Description=示例后台服务
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/demo-server
# 只在异常退出、超时等失败结果下尝试恢复
Restart=on-failure
# 避免进程刚退出就立刻再次占用资源
RestartSec=5s
# 限制短时间内的启动次数,便于暴露真正根因
StartLimitIntervalSec=60s
StartLimitBurst=5

[Install]
WantedBy=multi-user.target

这里不要用 Restart=always 来“修复”手动停止问题。它同样不能改变管理员明确停止的语义,却可能让正常退出的程序再次启动。若服务需要在某个维护脚本中恢复,脚本应显式调用 systemctl start demo.service,并把停机和恢复写入自己的变更记录。

已经停掉的服务如何安全恢复

确认停机是误操作或维护窗口已结束后,使用 start 让单元进入运行态;服务原本仍处于运行但需要重载进程时,才使用 restart。修改 unit 文件后先执行 daemon-reload,再按需启动:

# 重新读取 unit 文件,避免沿用旧配置
systemctl daemon-reload

# 手动停止后的明确恢复动作
systemctl start demo.service

# 检查恢复结果和最近日志
systemctl status demo.service --no-pager
journalctl -u demo.service -n 40 --no-pager

若启动失败,先看 systemctl status 的失败原因和日志,不要连续执行多次 restart 掩盖启动限流。达到 StartLimitBurst 后,systemd 可能暂时不再自动尝试;修好配置后再用 systemctl reset-failed demo.service 清理失败状态并重新启动。

常见问题

把 Restart=on-failure 改成 always 能自动拉起手动停止吗?

不能。由 systemd 执行的停止操作仍然不会按普通失败处理;需要恢复时应由运维脚本或管理员明确调用 start/restart。

服务显示 inactive 就代表它崩溃了吗?

不是。inactive 只描述当前状态,可能来自正常停止、依赖停止、关机或进程异常退出。结合 Result、主进程退出字段和 journalctl 日志判断。

为什么配置了 Restart=on-failure 还是没有重启?

除了手动停止,还要检查服务是否是 Type=oneshot、是否命中 RestartPreventExitStatus、是否触发启动限流,以及实际退出的是不是 systemd 追踪的主进程。

总结

Restart=on-failure 的重点是“失败后恢复”,不是“服务离开 active 就强行启动”。把人工停止、依赖事务、正常退出与真正故障分开记录,再用状态字段和日志复核,自动恢复策略才不会和维护操作互相打架。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go bufio.Scanner Split 自定义分词时为什么会漏掉最后一个 tokenGo bufio.Scanner Split 自定义分词时为什么会漏掉最后一个 token
上一篇
Go bufio.Scanner Split 自定义分词时为什么会漏掉最后一个 token
AbortController 取消 fetch 后如何清理未消费的 response body
下一篇
AbortController 取消 fetch 后如何清理未消费的 response body
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    62次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    224次使用
  • C-Eval中文评测基准:大语言模型多学科能力评估指南
    C-Eval
    深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
    148次使用
  • AI Prompt Library:免费AI提示词库,助力ChatGPT高效创作与营销
    AI Prompt Library
    探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
    80次使用
  • Generrated:DALL·E 2/3 AI绘画提示词灵感库与图像对比平台
    Generrated
    Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
    58次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码