Linux systemd.kill KillMode 怎样控制停止服务时的进程范围
如果一个 systemd 服务停止后仍有 worker、子进程或脚本残留,先看 KillMode=,不要只盯着 ExecStop=。它决定 systemd 停止 unit 时覆盖哪个进程范围:默认的 control-group 会处理整个控制组,mixed 会区分主进程与其余进程,process 只处理主进程,none 则不主动杀进程。
官方地址:https://www.freedesktop.org/software/systemd/man/latest/systemd.kill.html
常规服务优先保留默认的KillMode=control-group;只有明确知道子进程生命周期由别的管理器接管时,才考虑更窄的范围。process和none容易让进程脱离 systemd 的生命周期与资源管理。
先区分四种 KillMode 的进程范围
KillMode= 写在 unit 的 [Service] 等配置段中,核心不是“发什么信号”,而是“信号发给哪些对象”。官方文档列出四个取值:
| 取值 | 停止时的覆盖范围 | 适合怎样理解 |
|---|---|---|
control-group | 处理 unit 控制组中剩余的全部进程 | 默认、最容易保持生命周期一致 |
mixed | 先对主进程发首个终止信号,最终信号覆盖控制组中的剩余进程 | 主进程需要优雅退出,同时不放过子进程 |
process | 只处理主进程 | 范围很窄,官方不推荐常规使用 |
none | 不主动杀进程,只执行停止命令 | 极特殊场景,官方强烈不建议 |

这里的“控制组”可以理解为 systemd 为 unit 维护的进程边界。服务程序自己启动的 worker 不会因为它不是主进程就自动脱离这个边界;真正决定停止覆盖范围的是 unit 的 KillMode 和后续的超时处理。
用停止信号与超时规则理解最终结果
KillMode 只回答“覆盖谁”,停止过程还受到信号和超时配置影响。通常 systemd 会先发送 SIGTERM,也可以通过 KillSignal= 或重启专用的 RestartKillSignal= 改变首个信号。若进程在 TimeoutStopSec= 到期后仍未退出,并且没有关闭 SendSIGKILL=,systemd 会发送 SIGKILL,或发送 FinalKillSignal= 指定的最终信号。
因此,“停止后子进程还在”至少有三种可能:KillMode 只覆盖了主进程;首个信号没有被应用处理;或者服务仍处在停止超时窗口内。不要把尚未到达最终信号的中间状态误认为 KillMode 失效。
[Service] # 让 systemd 处理整个 unit 控制组,避免 worker 脱离服务生命周期。 KillMode=control-group # 先给应用优雅退出的机会,时间到后再进入最终信号阶段。 TimeoutStopSec=30s # 首个停止信号保持默认的 SIGTERM,应用可以在退出钩子中清理资源。 KillSignal=SIGTERM
如果应用确实需要生成转储来排查无法退出的原因,可以在充分了解后配置 FinalKillSignal=SIGABRT 等方案;这不是缩小 KillMode 的理由,且应同时考虑 core 文件限制和运维成本。
按服务结构选择配置
选型时先问“谁拥有子进程的生命周期”。如果 worker、脚本或辅助进程属于这个服务,通常希望 unit 停止后整个控制组都结束,使用默认的 control-group 更稳妥。若希望主进程先收到优雅退出信号,而在最终阶段清理整个控制组,可以选择 mixed。

process 只杀主进程,子进程可能继续运行;服务管理器又可能把 unit 视为已经停止,这会造成“服务状态正常但端口仍被占用”或旧 worker 继续消耗资源。none 更进一步,停止时不主动杀进程,只运行停止命令,残留进程与控制组可能继续存在。除非有非常明确的外部生命周期管理者,否则不要用这两个值掩盖应用退出问题。
一个更容易维护的选择表如下:
| 服务形态 | 优先选择 | 判断依据 |
|---|---|---|
| 主进程和 worker 都由 unit 管理 | control-group | 停止后不留下同一服务的子进程 |
| 主进程要优雅退出,最终还需清理 worker | mixed | 首个信号和最终信号的对象不同 |
| 子进程由外部 supervisor 接管 | 先确认所有权,再评估是否需要更窄范围 | 不能仅凭“启动方式不同”就改为 process |
| 希望停止后进程继续存活 | 不要默认使用 none | 先说明资源、端口和重启策略由谁负责 |
用 systemctl 检查实际控制组
修改 unit 之前,先把配置来源和当前进程信息分开查看。下面的命令只读取 unit 状态和属性,不会替读者执行停止操作:
# 查看最终合并后的 unit 配置,确认 KillMode 来自哪个片段。 systemctl cat demo.service # 读取主进程和控制组属性,辅助判断服务是否存在多个受管进程。 systemctl show demo.service -p MainPID -p ControlGroup -p KillMode # 只看当前 unit 的状态摘要,确认是否仍处在 stopping 状态。 systemctl status demo.service --no-pager
如果配置写在 drop-in 文件中,systemctl cat 比直接打开某个猜测路径更可靠,因为它会把主 unit 和附加片段一起展示。改完后可用 systemctl daemon-reload 让 systemd 重新读取配置;如果要观察新的停止行为,再由运维流程决定是否重启服务。
# 重新加载 unit 文件,不等同于停止或重启服务。 systemctl daemon-reload # 复查生效值,避免只看文件却遗漏 drop-in 覆盖。 systemctl show demo.service -p KillMode -p TimeoutStopUSec -p KillSignal
排查 KillMode 的四个检查点
- 先确认 unit 的最终
KillMode,不要只看某个原始模板文件。 - 再确认
MainPID和ControlGroup,把主进程与 worker 的关系弄清楚。 - 检查
TimeoutStopSec、KillSignal、SendSIGKILL和FinalKillSignal是否改变了停止阶段。 - 最后确认残留进程的真正所有者;如果是应用内部启动的子进程,优先修复优雅退出,而不是用
process或none放任它存活。
一句话记忆:control-group 关注“整个 unit 的进程边界”,mixed 关注“主进程先优雅、最终全组清理”,process 只处理主进程,none 不主动处理进程。先确定生命周期所有权,再决定是否偏离默认值。
相关问题
KillMode 默认值是什么?
官方文档给出的默认值是 control-group。除非有明确的进程所有权设计,否则通常不需要为了“停止更快”改成 process。
mixed 和 control-group 有什么区别?
mixed 会让首个终止信号只发给主进程,而后续最终信号覆盖控制组;control-group 则按控制组处理剩余进程。前者适合需要区分主进程优雅退出阶段的服务。
为什么服务停止了,子进程还在?
可能是 KillMode=process 或 none,也可能仍在停止超时窗口、首个信号没有被应用处理,或子进程不在该 unit 的控制组。先用 systemctl show 查看实际属性。
改了 KillMode 需要做什么?
先执行 systemctl daemon-reload 重新读取 unit 配置,再在合适的维护窗口观察服务的停止行为。不要把 daemon-reload 当成停止或重启命令。
Linux systemd.resource-control IOWeight 怎样分配服务之间的 IO 权重
- 上一篇
- Linux systemd.resource-control IOWeight 怎样分配服务之间的 IO 权重
- 下一篇
- Linux systemd.time 怎样区分时长表达式与时间点表达式
-
- 文章 · linux | 40分钟前 |
- Linux systemd.timer FixedRandomDelay 怎样保持随机延迟的稳定性
- 432浏览 收藏
-
- 文章 · linux | 44分钟前 |
- Linux systemd.unit AssertPathExists 怎样区分启动断言与启动条件
- 236浏览 收藏
-
- 文章 · linux | 45分钟前 | Linux · 服务管理 · Linux Type=notify READY=1 systemd.service sd_notify 服务初始化
- Linux systemd.service Type=notify 怎样声明服务初始化完成
- 390浏览 收藏
-
- 文章 · linux | 48分钟前 |
- Linux systemd.slice 怎样给同组服务设置资源父级
- 225浏览 收藏
-
- 文章 · linux | 48分钟前 |
- Linux systemd.mount 怎样让挂载单元等待网络可用
- 452浏览 收藏
-
- 文章 · linux | 49分钟前 | Linux ·
- Linux systemd.time 怎样区分时长表达式与时间点表达式
- 469浏览 收藏
-
- 文章 · linux | 54分钟前 |
- Linux systemd.resource-control IOWeight 怎样分配服务之间的 IO 权重
- 102浏览 收藏
-
- 文章 · linux | 56分钟前 |
- Linux systemd.exec LoadCredential 怎样向服务传入文件凭据
- 304浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux systemd.automount TimeoutIdleSec 怎样卸载空闲自动挂载点
- 488浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux systemd.socket Accept 怎样选择每连接服务实例
- 106浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux systemd.path PathChanged 怎样监视目录项变化
- 106浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 734次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 736次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 815次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 776次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 611次使用
-
- 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浏览

