Linux systemd发展演进与实战指南

Linux systemd 发展演进与实战指南

本文说明 systemd 为何成为主流 init/系统管理框架,梳理 SysVinit、Upstart 与 systemd 的演进关系,并给出工作原理、常用命令与典型单元文件解析。


目录

  • [一、背景:systemd 为何成为主流](#一、背景:systemd 为何成为主流)
  • [二、三代 init 要解决什么问题](#二、三代 init 要解决什么问题)
  • 三、发展简史
  • 四、工作原理
  • 五、启动流程概览
  • [六、日常使用:systemctl / target / journalctl](#六、日常使用:systemctl / target / journalctl)
  • [七、自定义 .service 示例](#七、自定义 .service 示例)
  • [八、案例:nginx.service 单元解析](#八、案例:nginx.service 单元解析)
  • 九、三代方案对比表

一、背景:systemd 为何成为主流

在 systemd 普及之前,Linux 多使用 SysVinit (串行启动、效率低)和 Upstart(事件驱动、并行更好,但设计复杂、与旧脚本兼容成本高)。

systemd 由 Lennart Poettering、Kay Sievers 等推动,目标:更快、能力更强、接口更统一,2010 年代起逐渐成为 Fedora、Ubuntu、Debian、RHEL/CentOS、openSUSE 等发行版默认 init。

维度 要点
启动快 依赖图并行启动;Socket/D-Bus 按需激活(如首次连 22 端口再拉起 sshd)
管理统一 服务、挂载、定时器等抽象为 Unit,取代零散 init 脚本
功能集成 内置 journald (日志)、networkd (网络)、udev (设备)、cgroups(资源)等
迁移成本 可兼容 SysVinit 脚本,平滑过渡

二、三代 init 要解决什么问题

三者都在解决同一问题:内核把控制权交给 PID 1 之后,如何把网络、存储、服务、运行级别等按正确顺序、高效拉起来,并在关机时有序收尾。

代际 角色概括
SysVinit 「清单式」管家:/etc/init.d/ + rcX.d 符号链接,按运行级别串行跑脚本
Upstart 「事件驱动」管家:网卡就绪、磁盘就绪等事件触发任务,可并行,但模型复杂、生态未统一
systemd 「系统级 CEO」:一切皆 Unit,PID 1 统一调度;并行 + 按需激活 + 日志/网络等一体化

SysVinit 典型痛点:串行慢;不维护服务「是否在跑」;改启动项要折腾链接;只管启停,不管日志与依赖表达。

Upstart 典型痛点:事件规则难调试;与 SysV 脚本折中导致设计不纯粹;未形成日志、设备等统一管理平台。

systemd 的定位 :不仅是启动器,而是系统管理框架 ,对外 largely systemctl / journalctl 一致接口。


三、发展简史

复制代码
2010 左右    systemd 项目启动
2011         Fedora 15 首个主流发行版默认 systemd
2012--2014    Arch、CoreOS 等跟进;Ubuntu 15.04 弃 Upstart 转 systemd
2014         Debian 技术委员会决议 Jessie 采用 systemd → 主流格局基本确定
现今         多数服务器/桌面发行版默认 systemd

四、工作原理

4.1 架构要点

  • PID 1systemd 回收僵尸进程、关机时按序结束子进程。
  • 家族进程systemd-journaldsystemd-networkdsystemd-resolvedsystemd-udevd 等与 PID 1 协同。

4.2 单元类型(Unit)

后缀 作用
.service 守护进程(如 nginx、sshd)
.socket 套接字,常用于 Socket 激活
.mount / .automount 挂载 / 自动挂载
.timer 定时任务(可替代部分 cron 场景)
.target 单元组,对应传统「运行级别」逻辑

配置文件一般为 INI 风格 ,路径多在 /lib/systemd/system//etc/systemd/system/

4.3 并行启动与按需激活

  • 并行 :根据 After/Before/Requires/Wants 建依赖图,无依赖的单元可同时启动。
  • Socket 激活 :先由 .socket 监听端口;首个连接到达再启动 .service,空闲后可停服务,省资源。

4.4 依赖关键字(简表)

指令 含义
After= / Before= 启动顺序先后(不必然强绑定成败)
Requires= 强依赖:被依赖单元失败则本单元失败
Wants= 弱依赖:被依赖失败本单元仍尝试启动
Conflicts= 互斥,不可同时 active

常见目标:multi-user.target(多用户文本)、graphical.target(图形会话)。


五、启动流程概览

复制代码
内核执行 /sbin/init(通常指向 systemd)
    → 扫描并加载 Unit,解析依赖图
    → 按 default.target(如 multi-user.target)并行拉起所需单元
    → 运行期监控服务,按配置自动重启等

六、日常使用:systemctl / target / journalctl

6.1 服务(.service)

bash 复制代码
sudo systemctl start nginx          # 启动(可写 nginx.service)
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx         # 不中断主进程的 reload(视服务支持)
sudo systemctl status nginx         # 状态 + 近期日志片段
sudo systemctl enable nginx         # 开机自启
sudo systemctl disable nginx
systemctl is-enabled nginx

6.2 Target 与电源

bash 复制代码
systemctl get-default
sudo systemctl set-default multi-user.target
sudo systemctl set-default graphical.target
sudo systemctl isolate multi-user.target   # 切换当前 target(如图形→多用户)
sudo systemctl poweroff
sudo systemctl reboot
sudo systemctl suspend

6.3 日志 journalctl

bash 复制代码
sudo journalctl              # 全部
sudo journalctl -b           # 本次启动以来
sudo journalctl -f           # 跟随
sudo journalctl -u nginx.service
sudo journalctl -p err       # 优先级过滤
sudo journalctl -u nginx -b -p err

七、自定义 .service 示例

文件:/etc/systemd/system/my_app.service

ini 复制代码
[Unit]
Description=My Custom Python App
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/my_app
ExecStart=/usr/bin/python3 /opt/my_app/my_app.py
Restart=on-failure

[Install]
WantedBy=multi-user.target
bash 复制代码
sudo systemctl daemon-reload
sudo systemctl start my_app
sudo systemctl enable my_app

八、案例:nginx.service 单元解析

以下结构与 Debian/Ubuntu 常见包内单元一致,具体以本机 systemctl cat nginx 为准。

ini 复制代码
[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target
段/项 说明
Description / Documentation status 展示;文档入口
After=... 在网络、远程文件系统、NSS 等就绪后再启
Wants=network-online.target 弱依赖「网络真正可用」
Type=forking 主进程 fork 后台化;需 PIDFile 让 systemd 跟踪 master
ExecStartPre -t 先测配置,失败则不启动
ExecReload 对应 systemctl reload,平滑重载
ExecStop 优雅退出(如 QUIT),- 前缀表示失败不致命
KillMode=mixed 停服时对主进程与其它 cgroup 进程的组合策略
PrivateTmp=true 独立 /tmp,减小横向影响
WantedBy=multi-user.target enable 时在 multi-user.target.wants/ 建链,进入多用户目标时拉起

九、三代方案对比表

特性 SysVinit Upstart systemd
核心模型 串行脚本 事件驱动 单元依赖图 + 并行
启动速度 较快 通常更快
管理方式 分散脚本 集中事件配置 Unit + systemctl 统一
功能范围 基本启停 启停 + 部分事件 服务、日志、网络、设备等
设计取向 简单、可移植 缓解启动瓶颈 高效、统一、功能全

根据公开资料与常见发行版行为整理;具体行为以本机 systemd 版本与单元文件为准。

相关推荐
白太岁2 小时前
Linux 进程调度模块
linux·运维·服务器
17(无规则自律)2 小时前
【Linux驱动实战】:最简单的内核模块
linux·c语言·驱动开发·嵌入式硬件
BioRunYiXue2 小时前
甘油不够了,能用植物油保存菌种吗?
java·linux·运维·服务器·网络·人工智能·eclipse
羸弱的穷酸书生2 小时前
跟AI学一手之运维Agent
运维·人工智能·agent
zhougl9962 小时前
Maven build配置
java·linux·maven
Predestination王瀞潞2 小时前
CentOS7虚拟机安装过程中没有打开网卡,ip addr无法查看es33这个情况下的解决方法
服务器·网络·tcp/ip
jianghao20253 小时前
realesrgan-gui跨平台使用指南:Win/Mac/Linux全支持
linux·windows·mac·跨平台软件·realesrgan-gui
Stark-C3 小时前
专为NAS用户打造的导航页,支持Docker管理,极空间部署FlatNas
运维·docker·容器
小王要努力上岸3 小时前
运维自动化工具 Ansible
运维·自动化·ansible