第 8 章 · 03 systemd 单元模型:不止是服务 本节摘要:很多人以为 systemd 只管「服务」(.service),其实它管的对象叫「单元(unit)」,服务只是其中一种。本节带你认识 systemd 的完整单元谱系: (长期运行的程序)、 (定时器,systemd 对 cron 的现代化重做)、 (按需启动,有连接才起服务)、 (挂载点)。理解这个单元模型,你才能理解 systemd 为什么被称为「系统的总管」——它把「一切该长期存在的东西」都用统一的方式管理起来。 内容来源:综合 systemd 知识整理,套用体系化模板。 学习目标 阅读完本节,你应当能够: 说清「单元(unit)」是 systemd 的管理对象,服务(.service)只是其中一种类型。
本节摘要:很多人以为 systemd 只管「服务」(.service),其实它管的对象叫「单元(unit)」,服务只是其中一种。本节带你认识 systemd 的完整单元谱系:
.service(长期运行的程序)、.timer(定时器,systemd 对 cron 的现代化重做)、.socket(按需启动,有连接才起服务)、.mount(挂载点)。理解这个单元模型,你才能理解 systemd 为什么被称为「系统的总管」——它把「一切该长期存在的东西」都用统一的方式管理起来。
内容来源:综合 systemd 知识整理,套用体系化模板。
阅读完本节,你应当能够:
.service、.timer、.socket、.mount、.target、.device。.timer 是 cron 的现代化替代,说清它的优势(依赖关系、错误处理、与 journald 集成)。.socket 的「按需启动」机制(有连接才起服务)。systemctl list-units/list-unit-files 按类型查看单元。systemd 的设计野心不只是「启动服务」,而是「用统一的方式管理系统上一切该长期存在的资源」。这些资源各不相同:
.service.timer.socket.mount.targetsystemd 把这些都抽象成「单元(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 是 systemd 对传统 cron 的重做,关联一个 .service,到点就触发那个 service。相对 cron 的优势:
Persistent=true 让错过的(关机期间)任务开机后补跑,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 实现「按需激活」:服务平时不跑,当有连接到来时,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 # 看某单元的依赖关系
systemctl enable backup.timer # 对! 启用 timer systemctl enable backup.service # 错! service 由 timer 触发, 不要直接 enable
timer 模式下,enable timer 而非 service。service 是被 timer 调用的「一次性任务」,不该自己常驻。
systemctl status backup.timer # 看 timer 状态 systemctl list-timers # 看下次触发时间 journalctl -u backup.service # 看有没有触发记录
timer 不触发常见原因:timer 没 --now 启动、.timer 文件语法错、关联的 .service 配置错。
systemctl cat nginx.service # 显示该单元的完整配置文件内容与路径 systemctl status nginx # Loaded 行也显示路径
单元文件通常在 /usr/lib/systemd/system/(系统自带,别改)或 /etc/systemd/system/(管理员自定义,优先级更高)。改自定义单元后要 systemctl daemon-reload 让 systemd 重新读配置。
.timer 是 cron 的现代化替代:优势是 journald 集成、依赖管理、错过补偿(Persistent=true)、错误重试;新系统优先用 timer。.socket 实现「按需启动」:平时不跑,有连接才瞬间起服务(如 cups 打印)。list-units --type=xxx 按类型、list-timers 看 timer、cat 单元 看配置、list-dependencies 看依赖。daemon-reload 让 systemd 重读配置。下一节讲传统的定时任务——crontab,它仍是广泛使用的「周期任务」方案,也是 timer 的前辈。