Linux systemd 服务管理模型详解

9次阅读

systemd服务管理是以单元为中心、依赖驱动、生命周期受控的现代模型;[Unit]定位启动顺序与依赖,[Service]定义进程行为与重启策略,配置应放/etc/systemd/system/并用daemon-reload生效。

Linux systemd 服务管理模型详解

systemd 服务管理不是“启动脚本的换皮”,而是一套以单元(Unit)为中心、依赖驱动、生命周期受控的现代服务模型。它把服务看作有明确状态、依赖关系和资源边界的实体,而不是一 start/stop 命令的集合。

service 文件的三个区块到底管什么

[Unit] 不是“描述信息区”,而是服务在系统启动图谱中的坐标定位器:它通过 After=Wants=Requires= 告诉 systemd “这个服务必须等 network.target 起完再动”、“它逻辑上需要 redis.service,但不强依赖”。写错这里,服务可能抢在网卡初始化前就启动失败,且 systemctl status 里根本看不到进程——因为压根没到执行那步。

[Service] 是真正的行为定义层,关键点在于:

  • Type= 必须匹配实际进程行为:simple(默认,主进程即服务进程)、forking(传统 daemon,需 PIDFile= 配合)、notify(如 sshd,启动后发 ready 信号);选错会导致 systemd 误判服务已就绪或卡在 “activating” 状态
  • ExecStart= 必须用绝对路径,且不能带 shell 语法(如 &&|);想做前置检查?用 ExecStartPre=
  • Restart=on-failure 不等于“挂了就拉起来”——它只对非 0 退出、被 kill、超时等情况生效;若进程静默卡死,得配合 WatchdogSec=RestartSec=

/etc/systemd/system/ vs /usr/lib/systemd/system/ 的覆盖规则

修改服务配置时,直接改 /usr/lib/systemd/system/xxx.service 是危险操作:软件包升级会直接覆盖它,导致配置丢失。正确做法是:

  • 复制原文件到 /etc/systemd/system/xxx.service(注意:是完整文件,不是软链)
  • /etc/systemd/system/ 下编辑,优先级最高,100% 生效
  • 运行 systemctl daemon-reload 后,用 systemctl cat xxx 验证看到的是你改的那份
  • 如果只想覆盖某几行(比如只改 User=),可用 .d/*.conf 片段目录:创建 /etc/systemd/system/xxx.service.d/override.conf,里面只写要覆盖的部分

服务起不来?先别急着查日志,做三件事

90% 的“服务启动失败”其实卡在加载阶段,journalctl -u xxx 可能一片空白。先确认基础事实:

  • 运行 systemctl list-unit-files | grep xxx,看服务是否被识别为 enabled/disabled —— 如果没列出来,说明文件没放对位置或后缀不对(比如写成 .service.txt
  • 运行 systemctl show xxx --Property=FragmentPath,确认 systemd 实际加载的是哪个路径下的文件
  • 运行 systemctl is-active xxxsystemctl is-failed xxx,区分是“没启”还是“启失败”;若返回 inactive 但没报错,大概率是 [Install] 区块缺失或 WantedBy= 写错(比如写成 graphical.target 却在 server 环境)

真正麻烦的从来不是写配置,而是理解 systemd 把“服务”抽象成了一个有拓扑关系、状态机和资源容器的单元——它不接受“差不多能跑就行”的模糊逻辑,每个字段都在参与调度决策。漏掉一个 After=,或误设 Type=,都可能让服务在某个环境里彻底失联,且错误表现毫无规律。

text=ZqhQzanResources