一、systemd 与 systemctl 概述
1.1 从 SysVinit 到 systemd
Linux 系统的初始化系统经历了从传统的 SysVinit 到 Upstart,再到如今广泛使用的 systemd 的演进。systemd 由 Lennart Poettering 开发,采用并行启动、依赖管理和单元(Unit)抽象,显著提升了系统启动速度和管理灵活性。
systemctl 是 systemd 的主命令行工具,用于控制 systemd 系统和服务管理器。它提供了对系统状态、服务生命周期、电源管理和日志的统一操作接口。
1.2 核心概念:Unit(单元)
systemd 将系统需要管理的所有对象抽象为 Unit(单元)。每个单元由配置文件定义,存放在 /usr/lib/systemd/system/、/etc/systemd/system/ 等目录中。
graph TD
A[systemd Unit 类型] --> B[.service]
A --> C[.timer]
A --> D[.socket]
A --> E[.target]
A --> F[.mount]
A --> G[.path]
A --> H[.slice]
A --> I[.scope]
B --> B1[后台守护进程<br/>sshd / nginx / mysql]
C --> C1[定时触发器<br/>替代传统 cron]
D --> D1[套接字激活<br/>按需启动服务]
E --> E1[运行目标<br/>替代 runlevel]
F --> F1[文件系统挂载]
G --> G1[路径监控<br/>文件变化触发]
H --> H1[Cgroup 资源组]
I --> I1[外部进程组]
style A fill:#e1f5fe
style B fill:#fff3e0
style E fill:#f3e5f5
二、systemctl 基础命令体系
2.1 服务生命周期管理
这是 systemctl 最常用的功能,控制服务的启动、停止和重启。
flowchart LR
subgraph 命令输入
A[systemctl]
end
subgraph 动作指令
A --> B[start]
A --> C[stop]
A --> D[restart]
A --> E[reload]
A --> F[enable]
A --> G[disable]
A --> H[status]
end
subgraph 作用对象
B --> I[服务单元.service]
C --> I
D --> I
E --> I
F --> I
G --> I
H --> I
end
subgraph 系统响应
I --> J[调用 systemd<br/>守护进程]
J --> K[执行单元配置<br/>ExecStart/ExecStop]
K --> L[更新系统状态<br/>写入 PID / 日志]
end
style A fill:#ffccbc
style J fill:#c8e6c9
常用生命周期命令:
| 命令 | 作用 | 立即生效 | 重启后保持 |
|---|---|---|---|
systemctl start <unit> |
启动单元 | ✅ | ❌ |
systemctl stop <unit> |
停止单元 | ✅ | ❌ |
systemctl restart <unit> |
重启单元 | ✅ | ❌ |
systemctl reload <unit> |
平滑重载配置 | ✅ | ❌ |
systemctl enable <unit> |
开机自启 | ❌ | ✅ |
systemctl disable <unit> |
取消开机自启 | ❌ | ✅ |
systemctl is-active <unit> |
检查是否运行 | - | - |
systemctl is-enabled <unit> |
检查是否自启 | - | - |
2.2 服务状态转换模型
systemd 中每个服务单元都有明确的状态机。
stateDiagram-v2
[*] --> inactive : 系统启动/单元创建
inactive --> activating : systemctl start
activating --> active : ExecStart 成功
activating --> failed : ExecStart 失败 / 超时
active --> deactivating : systemctl stop
active --> reloading : systemctl reload
reloading --> active : ExecReload 成功
deactivating --> inactive : ExecStop 完成
deactivating --> failed : ExecStop 失败
failed --> inactive : systemctl reset-failed
failed --> activating : systemctl restart
note right of active
运行中状态
进程 PID 已分配
资源已加载
end note
note left of failed
失败状态
需查看日志排查
journalctl -u unit
end note
状态查看示例:
# 查看单个服务详细状态
systemctl status sshd.service
# 输出示例解析:
● sshd.service - OpenSSH server
Loaded: loaded (/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-01-15 09:23:17 CST; 2 weeks ago
Docs: man:sshd(8), man:sshd_config(5)
Main PID: 1234 (sshd)
Tasks: 1 (limit: 4915)
Memory: 5.2M
CGroup: /system.slice/sshd.service
└─1234 /usr/sbin/sshd -D
三、Unit 配置文件解析
3.1 服务单元文件结构
以 .service 为例,配置文件通常包含三个段落:[Unit]、[Service]、[Install]。
graph LR
subgraph 服务单元配置文件
A[Unit] --> A1[Description<br/>Documentation<br/>After / Before / Wants<br/>Requires / Conflicts]
B[Service] --> B1[Type<br/>ExecStart / ExecStop<br/>Restart<br/>User / Group<br/>Environment]
C[Install] --> C1[WantedBy<br/>RequiredBy]
end
A1 --> D[依赖与元数据]
B1 --> E[进程行为定义]
C1 --> F[开机挂载点]
style A fill:#e3f2fd
style B fill:#e8f5e9
style C fill:#fff3e0
典型服务配置示例:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Server
Documentation=https://example.com/docs
After=network.target postgresql.service
Requires=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myapp --config /etc/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure
RestartSec=5s
User=appuser
Group=appgroup
Environment="APP_ENV=production"
EnvironmentFile=/etc/myapp/env
[Install]
WantedBy=multi-user.target
3.2 Service Type 详解
Type= 决定了 systemd 如何判断服务启动完成。
flowchart TD
A[Service Type] --> B[simple]
A --> C[exec]
A --> D[forking]
A --> E[oneshot]
A --> F[dbus]
A --> G[notify]
A --> H[idle]
B --> B1[ExecStart 主进程<br/>systemd 认为立即启动完成<br/>最常用]
C --> C1[ExecStart 调用后<br/>execve 成功即算启动完成<br/>比 simple 更精确]
D --> D1[经典守护进程模式<br/>父进程 fork 后退出<br/>需配 PIDFile]
E --> E1[执行一次即退出<br/>常用于初始化脚本<br/>RemainAfterExit=yes]
F --> F1[等待 D-Bus 名称出现<br/>服务注册 bus 后才算就绪]
G --> G1[等待 sd_notify 信号<br/>服务主动通知就绪<br/>最精确但需代码支持]
H --> H1[延迟到系统空闲时启动<br/>减少启动竞争]
style A fill:#fce4ec
style B fill:#e8f5e9
style G fill:#fff8e1
四、系统状态与电源管理
4.1 Target(目标):运行级别的新抽象
systemd 用 Target 替代了传统的 SysVinit runlevel(0-6)。
graph BT
A[graphical.target<br/>图形界面] --> B[multi-user.target<br/>多用户命令行]
B --> C[basic.target<br/>基本系统初始化]
C --> D[sysinit.target<br/>系统初始化]
D --> E[local-fs.target<br/>本地文件系统就绪]
F[rescue.target<br/>救援模式] --> C
G[emergency.target<br/>紧急模式] --> E
H[reboot.target<br/>重启] --> I[shutdown.target]
J[poweroff.target<br/>关机] --> I
style A fill:#c8e6c9
style B fill:#bbdefb
style F fill:#ffccbc
style J fill:#ffccbc
Target 切换命令:
systemctl isolate multi-user.target # 切换到命令行模式
systemctl isolate graphical.target # 切换到图形界面
systemctl rescue # 进入救援模式
systemctl emergency # 进入紧急模式
systemctl reboot # 重启系统
systemctl poweroff # 关机
4.2 查看默认 Target
systemctl get-default
# 输出: graphical.target 或 multi-user.target
systemctl set-default multi-user.target # 设置默认启动到命令行
五、依赖管理与启动顺序
5.1 依赖关系类型
systemd 通过多种指令定义单元间的依赖关系。
graph LR
A[httpd.service] -->|Requires| B[network.target]
A -->|Wants| C[remote-fs.target]
A -->|After| D[postgresql.service]
A -->|Before| E[nginx.service]
F[firewalld.service] -->|Conflicts| G[ufw.service]
style A fill:#e3f2fd
style B fill:#fff3e0
style G fill:#ffccbc
| 指令 | 语义 | 失败传播 | 启动顺序 |
|---|---|---|---|
Requires= |
强依赖 | 是(本单元失败) | 不控制顺序 |
Wants= |
弱依赖 | 否 | 不控制顺序 |
Requisite= |
存在性检查 | 是 | 启动前检查 |
BindsTo= |
绑定依赖 | 是 | 依赖停止则本单元停止 |
PartOf= |
部分依赖 | 是 | 仅控制 stop/restart |
After= |
顺序在后 | - | 仅顺序,不建立依赖 |
Before= |
顺序在前 | - | 仅顺序,不建立依赖 |
Conflicts= |
互斥 | - | 启动时停止对方 |
5.2 依赖解析实例
# 查看服务的依赖树
systemctl list-dependencies sshd.service
# 反向依赖:谁依赖我
systemctl list-dependencies sshd.service --reverse
六、定时任务:Timer 单元
systemd Timer 是现代 Linux 替代 cron 的定时机制,具备更好的日志集成和依赖管理。
gantt
title Timer 触发模式对比
dateFormat X
axisFormat %s
section RealtimeTimer
日历触发 :a1, 0, 2
固定时间点执行 :a2, 2, 2
section MonotonicTimer
系统启动后 :b1, 0, 2
单元激活后 :b2, 2, 2
定时器激活后 :b3, 4, 2
Timer 配置示例:
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily Backup Timer
[Timer]
OnCalendar=daily # 每天执行
OnCalendar=*-*-* 02:00:00 # 每天凌晨2点
Persistent=true # 如果错过,开机后补执行
Unit=backup.service
[Install]
WantedBy=timers.target
# 查看所有定时器
systemctl list-timers --all
# 输出列说明:
# NEXT LEFT LAST PASSED UNIT ACTIVATES
# Tue 09:00 3h 20min Mon 09:00 20h ago backup.timer backup.service
七、日志管理:journalctl
systemd 集成了日志系统 journald,通过 journalctl 查询。
flowchart LR
A[服务进程] -->|stdout/stderr<br/>syslog| B[systemd-journald]
B --> C[/run/log/journal<br/>内存日志]
B --> D[/var/log/journal<br/>持久化日志]
E[journalctl] -->|查询| D
E -->|查询| C
style B fill:#e3f2fd
style E fill:#c8e6c9
常用 journalctl 命令:
journalctl -u nginx.service # 查看 nginx 服务日志
journalctl -u nginx -f # 实时跟踪
journalctl --since "1 hour ago" # 最近1小时
journalctl --since today --until now # 今天至今
journalctl -p err # 仅错误级别
journalctl --vacuum-time=7d # 清理7天前日志
journalctl --disk-usage # 查看日志占用空间
八、高级用法与故障排查
8.1 环境变量与参数传递
# 查看服务的环境变量
systemctl show sshd.service -p Environment
# 查看服务执行命令
systemctl show sshd.service -p ExecStart
# 查看服务运行用户
systemctl show sshd.service -p User -p Group
8.2 故障排查流程
flowchart TD
A[服务启动失败] --> B{查看状态}
B -->|systemctl status unit| C[分析错误信息]
C --> D{Active: failed?}
D -->|是| E[journalctl -u unit]
D -->|否| F[检查依赖]
E --> G{日志提示?}
G -->|权限拒绝| H[检查 User/Group<br/>文件权限]
G -->|找不到文件| I[检查 ExecStart 路径]
G -->|端口占用| J[检查 Conflicts<br/>网络绑定]
F --> K[systemctl list-dependencies]
K --> L{依赖失败?}
L -->|是| M[递归排查上游单元]
L -->|否| N[检查 After/Before 死锁]
style A fill:#ffccbc
style H fill:#fff9c4
style I fill:#fff9c4
style J fill:#fff9c4
8.3 常用诊断命令速查
# 1. 查看失败单元
systemctl --failed
# 2. 重置失败状态
systemctl reset-failed
# 3. 查看单元加载问题
systemctl list-unit-files --state=enabled
# 4. 验证配置语法
systemd-analyze verify /etc/systemd/system/myunit.service
# 5. 分析启动耗时
systemd-analyze blame # 各服务耗时排名
systemd-analyze critical-chain # 关键路径
# 6. 编辑单元配置
systemctl edit --full nginx.service # 完整覆盖
systemctl edit nginx.service # 创建 drop-in 覆盖
# 7. 守护进程重载
systemctl daemon-reload # 修改配置后必须执行
九、完整命令索引
mindmap
root((systemctl))
服务控制
start
stop
restart
reload
kill
开机管理
enable
disable
is-enabled
reenable
状态查询
status
is-active
is-failed
show
list-units
list-unit-files
依赖管理
list-dependencies
add-wants
add-requires
电源管理
reboot
poweroff
suspend
hibernate
系统控制
daemon-reload
daemon-reexec
set-default
get-default
isolate
十、总结
systemctl 是现代 Linux 系统管理的核心工具,它将服务生命周期、依赖解析、定时任务、日志查询和电源管理统一在一致的命令接口下。掌握 systemctl 意味着:
- 理解 Unit 抽象 —— 所有系统资源都是可配置、可依赖的单元
- 掌握状态机 —— 明确 active/inactive/failed 的转换条件
- 善用依赖指令 —— 正确配置
Wants/Requires/After/Before - 结合 journalctl —— 日志是排查服务故障的第一线索
对于系统管理员和运维工程师,熟练运用 systemctl 是保障服务高可用性和系统稳定性的基础技能。
原文 https://blog.csdn.net/2301_79518550/article/details/161803659