第 8 章 · 03 systemd 单元模型:不止是服务


文档摘要

第 8 章 · 03 systemd 单元模型:不止是服务 本节摘要:很多人以为 systemd 只管「服务」(.service),其实它管的对象叫「单元(unit)」,服务只是其中一种。本节带你认识 systemd 的完整单元谱系: (长期运行的程序)、 (定时器,systemd 对 cron 的现代化重做)、 (按需启动,有连接才起服务)、 (挂载点)。理解这个单元模型,你才能理解 systemd 为什么被称为「系统的总管」——它把「一切该长期存在的东西」都用统一的方式管理起来。 内容来源:综合 systemd 知识整理,套用体系化模板。 学习目标 阅读完本节,你应当能够: 说清「单元(unit)」是 systemd 的管理对象,服务(.service)只是其中一种类型。

第 8 章 · 03 systemd 单元模型:不止是服务

本节摘要:很多人以为 systemd 只管「服务」(.service),其实它管的对象叫「单元(unit)」,服务只是其中一种。本节带你认识 systemd 的完整单元谱系:.service(长期运行的程序)、.timer(定时器,systemd 对 cron 的现代化重做)、.socket(按需启动,有连接才起服务)、.mount(挂载点)。理解这个单元模型,你才能理解 systemd 为什么被称为「系统的总管」——它把「一切该长期存在的东西」都用统一的方式管理起来。

内容来源:综合 systemd 知识整理,套用体系化模板。

学习目标

阅读完本节,你应当能够:

  1. 说清「单元(unit)」是 systemd 的管理对象,服务(.service)只是其中一种类型。
  2. 列举主要单元类型:.service.timer.socket.mount.target.device
  3. 理解 .timer 是 cron 的现代化替代,说清它的优势(依赖关系、错误处理、与 journald 集成)。
  4. 理解 .socket 的「按需启动」机制(有连接才起服务)。
  5. systemctl list-units/list-unit-files 按类型查看单元。

一、设计动机:统一管理「一切该长期存在的东西」

systemd 的设计野心不只是「启动服务」,而是「用统一的方式管理系统上一切该长期存在的资源」。这些资源各不相同:

  • 一个长期运行的程序(Nginx)——.service
  • 一个定时任务(每天备份)——.timer
  • 一个监听端口(有连接才启动 inetd 式服务)——.socket
  • 一个挂载点(挂 /dev/sda1 到 /mnt)——.mount
  • 一组服务的集合(进入图形界面)——.target

systemd 把这些都抽象成「单元(unit)」,每个单元一个 .type 文件,用 systemctl 统一管理。这就是为什么 systemctl 能 start/restart/enable 这么多不同类型的东西——它们在 systemd 看来都是「单元」,接口统一。

二、主要单元类型

类型 扩展名 含义 典型用途
service .service 长期运行的程序 nginx.service、sshd.service
timer .timer 定时触发器(关联一个 service) 每天备份的 backup.timer
socket .socket 监听套接字(按需激活 service) cups.socket(有打印请求才起服务)
mount .mount 文件系统挂载点 home.mount
target .target 单元集合(一组服务的「里程碑」) multi-user.target(多用户模式)、graphical.target
device .device 内核设备 (udev 自动生成)
path .path 路径变化触发(如目录有新文件) 监控某目录有新文件就处理

.timer:cron 的现代化替代

.timer 是 systemd 对传统 cron 的重做,关联一个 .service,到点就触发那个 service。相对 cron 的优势:

  • 与 journald 集成:timer 触发的 service 日志自动进 journal,可查。
  • 依赖管理:timer 可声明「依赖某 service 先就绪」,cron 做不到。
  • 错过补偿:Persistent=true 让错过的(关机期间)任务开机后补跑,cron 做不到。
  • 错误处理与重试:service 的 Restart 设定可自动重试,cron 要自己写。
# 一个 timer 单元长这样(定义在 .timer 文件里) [Timer] OnCalendar=daily # 每天触发 Persistent=true # 错过的开机补跑 Unit=backup.service # 触发哪个 service systemctl enable --now backup.timer # 启用 timer(注意是 enable timer, 不是 service) systemctl list-timers # 列所有 timer

💡 技巧:新系统优先用 .timer 替代 cron——日志集成、依赖管理、错过补偿都是优势。cron 仍可用(兼容、简单),但 timer 是 systemd 时代的现代方式。

.socket:按需启动

.socket 实现「按需激活」:服务平时不跑,当有连接到来时,systemd 通过 .socket 拦截连接、瞬间启动对应 .service、把连接转交给它。好处:不常用的服务平时不占内存,要用时秒起。典型例子是 cups(打印服务)——平时不跑,有打印请求才起。

三、查单元

systemctl list-units # 所有已加载的单元(各种类型) systemctl list-units --type=service # 只看 service systemctl list-units --type=timer # 只看 timer systemctl list-timers # 专看 timer(含下次触发时间) systemctl list-unit-files --type=service # 所有 service(含未加载的) systemctl list-dependencies nginx.service # 看某单元的依赖关系

四、踩坑与排错

坑 1:timer 与 service 的 enable 关系

systemctl enable backup.timer # 对! 启用 timer systemctl enable backup.service # 错! service 由 timer 触发, 不要直接 enable

timer 模式下,enable timer 而非 service。service 是被 timer 调用的「一次性任务」,不该自己常驻。

坑 2:timer 不触发

systemctl status backup.timer # 看 timer 状态 systemctl list-timers # 看下次触发时间 journalctl -u backup.service # 看有没有触发记录

timer 不触发常见原因:timer 没 --now 启动、.timer 文件语法错、关联的 .service 配置错。

坑 3:不知道某单元文件在哪

systemctl cat nginx.service # 显示该单元的完整配置文件内容与路径 systemctl status nginx # Loaded 行也显示路径

单元文件通常在 /usr/lib/systemd/system/(系统自带,别改)或 /etc/systemd/system/(管理员自定义,优先级更高)。改自定义单元后要 systemctl daemon-reload 让 systemd 重新读配置。

本节要点回顾

  1. systemd 管理的对象叫「单元(unit)」,服务(.service)只是其中一种;还有 timer/socket/mount/target 等。
  2. .timer 是 cron 的现代化替代:优势是 journald 集成、依赖管理、错过补偿(Persistent=true)、错误重试;新系统优先用 timer。
  3. .socket 实现「按需启动」:平时不跑,有连接才瞬间起服务(如 cups 打印)。
  4. timer 模式下 enable timer 而非 service——service 由 timer 触发,不该自己常驻。
  5. 查单元:list-units --type=xxx 按类型、list-timers 看 timer、cat 单元 看配置、list-dependencies 看依赖。
  6. 改自定义单元后 daemon-reload 让 systemd 重读配置。

下一节讲传统的定时任务——crontab,它仍是广泛使用的「周期任务」方案,也是 timer 的前辈。


发布者: 作者: 灏天文库 转发
评论区 (0)
U