一、systemd 概述
1. 定位与作用
- init 系统替代品:作为 Linux 系统的第 1 个进程(PID=1),替代传统的 SysVinit 和 Upstart,负责管理系统服务、启动流程、资源分配等。
- 统一管理 :通过 单元(Unit) 抽象各类系统资源,包括服务(service)、套接字(socket)、设备(device)、挂载点(mount)、目标(target)等。
- 设计目标:高性能(并行启动)、高可用性、模块化、标准化配置。
2. 核心组件
- systemd:主程序,作为 init 进程运行。
- systemctl:核心命令行工具,用于管理单元(启动/停止/重启服务、查看状态等)。
- systemd-analyze:分析系统启动时间、依赖关系等。
- journalctl:查看系统日志(与 systemd-journald 日志系统集成)。
- 其他工具 :如
hostnamectl
(主机名管理)、timedatectl
(时间管理)等。

二、服务单元(.service)核心概念
服务单元 是 systemd 中最常用的单元类型,用于管理后台服务(如 sshd
、httpd
)。
三、服务单元文件结构
服务单元文件通常位于:
- 系统服务 :
/etc/systemd/system/
(用户自定义)、/usr/lib/systemd/system/
(官方默认)。 - 用户服务 :
~/.config/systemd/user/
(仅当前用户可用)。
文件命名规则 :服务名.service
(如 nginx.service
)。
典型文件示例:
ini
[Unit]
Description=NGINX Web Server
Documentation=man:nginx(8)
After=network.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/usr/sbin/nginx -s stop
Restart=on-failure
RestartSec=5
User=nginx
Group=nginx
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target:将此服务添加到 multi-user.target(多用户运行级别)的依赖列表中。当系统进入多用户模式时,会自动启动此服务。这相当于传统的 "开机自启" 设置。WantedBy 表示软依赖(通过符号链接实现),如果服务启动失败,不会影响目标的激活。
四、单元文件核心段(Section)
1. [Unit] 段:通用配置
- Description:服务描述,供用户阅读。
- Documentation:文档路径(支持 URL、man 手册等)。
- 依赖关系 :
- After=xxx.target :本服务在
xxx.target
之后启动(不检查依赖是否成功)。 - Before=xxx.target :本服务在
xxx.target
之前启动。 - Requires=xxx.service :强依赖,若依赖的服务启动失败,本服务也会失败(如
Requires=network.service
)。 - Wants=xxx.service :弱依赖,依赖的服务启动失败不影响本服务(如
Wants=network-online.target
)。 - BindsTo=xxx.service:与依赖服务生命周期绑定(同生共死)。
- After=xxx.target :本服务在
- 冲突关系 :
- Conflicts=xxx.service :禁止与指定服务同时运行(如
Conflicts=apache2.service
)。
- Conflicts=xxx.service :禁止与指定服务同时运行(如
2. [Service] 段:服务核心配置
-
Type=:定义服务进程模型(关键配置):
类型 说明 典型场景 simple
主进程为前台进程(默认值),systemd 认为服务启动成功当 ExecStart
运行后。大多数现代服务(如 Node.js) forking
主进程启动后 fork 子进程,父进程退出(通过 PIDFile
指定子进程 PID)。传统 Unix 守护进程(如 Nginx) oneshot
一次性任务(执行完 ExecStart
即退出),需配合RemainAfterExit=yes
保持单元激活。数据备份、初始化脚本 dbus
需获取 D-Bus 名称后才算启动成功(通过 BusName=
指定名称)。依赖 D-Bus 的服务 notify
通过 sd_notify
接口通知 systemd 启动完成(需程序支持)。支持通知协议的服务 idle
所有非空闲任务完成后才启动服务。 低优先级任务(如日志轮转) -
进程管理:
ExecStart=
:启动服务的命令或脚本(必填)。ExecStartPre=
:启动前执行的命令(可多次定义,按顺序执行)。ExecStartPost=
:启动后执行的命令。ExecReload=
:重新加载配置的命令(如kill -HUP $PID
)。ExecStop=
:停止服务的命令(默认kill -TERM $MAINPID
)。ExecStopPost=
:停止后执行的命令。PIDFile=
:指定 PID 文件路径(配合Type=forking
使用)。
-
重启策略:
Restart=
:控制服务崩溃后的重启行为,可选值:no
(默认):不重启。on-success
:仅在正常退出时重启(非错误退出不重启)。on-failure
:异常退出时重启(如退出码非 0、被信号终止)。on-abnormal
:因信号(非SIGTERM
/SIGKILL
)或超时退出时重启。on-watchdog
:触发 watchdog 超时(需配置WatchdogSec=
)时重启。always
:无论何种原因退出,始终重启。
RestartSec=
:重启前的等待时间(默认 10s)。StartLimitInterval=
:限制单位时间内的重启次数(防雪崩,如StartLimitInterval=5s
)。
-
资源限制:
CPUQuota=
:限制 CPU 使用率(如CPUQuota=50%
,需内核支持 CGroups)。MemoryLimit=
:限制内存使用(如MemoryLimit=1G
)。LimitNOFILE=
:最大打开文件数(如LimitNOFILE=10240
)。TasksMax=
:限制进程数(如TasksMax=500
)。
-
安全设置:
User=
/Group=
:以指定用户/组运行服务(避免 root 权限)。PrivateTmp=
:为服务创建独立的临时目录(默认yes
,隔离文件系统)。ProtectSystem=
:限制对系统文件的访问(如ProtectSystem=strict
禁止访问/usr
//etc
)。
-
环境变量:
Environment=
:直接设置环境变量(如Environment="HTTP_PROXY=http://proxy.example.com"
)。EnvironmentFile=
:从文件读取环境变量(如EnvironmentFile=/etc/sysconfig/nginx
)。
3. [Install] 段:安装与激活配置
- WantedBy=target :将服务添加到指定目标的依赖列表(最常用,相当于"开机自启")。
- 示例:
WantedBy=multi-user.target
(多用户模式启动)、WantedBy=graphical.target
(图形界面模式启动)。
- 示例:
- RequiredBy=target:强依赖,目标启动时必须启动本服务(慎用,避免循环依赖)。
- Alias= :为服务创建别名(如
Alias=nginx-server.service
)。
五、服务管理常用命令(systemctl)
操作 | 命令示例 | 说明 |
---|---|---|
查看所有服务 | systemctl list-units --type=service --all |
包括活跃、非活跃、失败的服务 |
查看活跃服务 | systemctl list-units --type=service |
仅显示运行中的服务 |
启动服务 | systemctl start nginx.service |
立即启动服务 |
停止服务 | systemctl stop nginx.service |
立即停止服务 |
重启服务 | systemctl restart nginx.service |
先停止再启动 |
重新加载配置 | systemctl reload nginx.service |
不重启服务,仅重新加载配置 |
查看服务状态 | systemctl status nginx.service |
显示运行状态、日志等 |
启用开机自启 | systemctl enable nginx.service |
写入默认运行目标(如 multi-user.target ) |
禁用开机自启 | systemctl disable nginx.service |
移除开机自启配置 |
查看服务依赖关系 | systemctl list-dependencies nginx.service |
显示直接/间接依赖 |
临时激活服务(重启后失效) | systemctl start nginx.service --now |
仅本次启动有效 |
查看用户服务 | systemctl --user list-units --type=service |
管理当前用户的服务 |
六、高级特性与最佳实践
1. 服务依赖与启动顺序
- 避免循环依赖 :如
A.Requires=B
且B.Requires=A
,systemd 会拒绝启动。 - 按需启动(Socket 激活) :通过
.socket
单元监听端口,仅当有请求时启动服务(如sshd.socket
激活sshd.service
)。- 优势:减少资源占用,延迟启动服务。
2. 资源隔离与容器化
- systemd-nspawn:轻量级容器工具,基于 systemd 实现进程隔离。
- Scope 单元 :动态创建的临时单元(如
systemd-run --scope --user my-script.sh
),用于短期任务。
3. 日志管理(journalctl)
-
服务日志默认由
systemd-journald
收集,可通过journalctl
查看:bashjournalctl -u nginx.service # 查看指定服务日志 journalctl -u nginx --since today # 查看今日日志 journalctl -f -u nginx # 实时跟踪日志
-
配置日志持久化:修改
/etc/systemd/journald.conf
,设置Storage=persistent
并重启systemd-journald
服务。
4. 系统启动目标(Target)
-
传统运行级别映射 :
systemd 目标 传统运行级别 说明 graphical.target
5 图形界面多用户模式 multi-user.target
3 无图形界面多用户模式 rescue.target
1 单用户救援模式 emergency.target
0 紧急 Shell(无文件系统挂载) shutdown.target
6 关机 -
切换目标 :
bashsystemctl isolate multi-user.target # 切换至多用户模式 systemctl set-default graphical.target # 设置默认启动目标为图形界面
5. 用户服务(User Services)
-
用于管理当前用户的后台进程(如个人脚本、GUI 工具),优势:
- 无需 root 权限,随用户登录自动启动。
- 配置文件位于
~/.config/systemd/user/
。
-
示例:定义一个用户级别的定时备份服务:
ini[Unit] Description=Daily Backup Service [Service] Type=oneshot ExecStart=/home/user/backup.sh [Install] WantedBy=default.target
激活:
systemctl --user enable --now daily-backup.service
七、故障排查与性能优化
-
启动时间分析 :
bashsystemd-analyze blame # 按耗时排序启动项 systemd-analyze plot > boot.svg # 生成启动时间可视化图表
-
服务状态诊断 :
systemctl status service-name
查看运行状态,注意Active:
字段(active(running)
表示正常,active(failed)
表示异常)。- 检查日志中是否有错误信息(
journalctl -u service-name
)。
-
依赖循环排查 :
bashsystemctl list-dependencies --reverse service-name # 反向查看依赖链
-
资源限制调优 :
- 若服务频繁崩溃,尝试增加
MemoryLimit=
或调整Restart=
策略。 - 使用
systemd-cgtop
实时监控服务资源占用。
- 若服务频繁崩溃,尝试增加
八、自定义服务示例
bash
[Unit]
Description=ROS2 Vision Launch Service
After=network.target
[Service]
Type=simple
User=kyle
ExecStartPre=/bin/sleep 5
ExecStart=/bin/bash -c 'cd /home/kyle/RM/Observation_of_whole_robot && source install/setup.bash && ros2 launch rm_vision_bringup vision_bringup.launch.py'
Restart=always
RestartSec=5
# 防止服务重启过快导致资源耗尽
StartLimitInterval=60s
StartLimitBurst=3
[Install]
WantedBy=multi-user.target
启用并启动服务
bash
sudo systemctl daemon-reload #重载 systemd 配置
sudo systemctl enable ros2_vision.service #激活服务
sudo systemctl start ros2_vision.service
检查服务的状态
bash
sudo systemctl status ros2_vision.service
九、注意事项与陷阱
- 避免直接修改官方服务文件 :
- 官方服务文件位于
/usr/lib/systemd/system/
,修改后可能被系统更新覆盖。 - 正确做法:通过
systemctl edit service-name
创建覆盖文件(存于/etc/systemd/system/service-name.d/
)。
- 官方服务文件位于
- Type 配置错误 :
- 若
Type=forking
但未指定PIDFile=
,systemd 会误认为服务启动失败。
- 若
- 环境变量作用域 :
EnvironmentFile=
引用的文件需注意权限(建议权限644
,避免敏感信息泄露)。
- 资源限制的内核支持 :
- CGroups 相关配置(如
MemoryLimit=
)需内核启用 CGroups v2,否则可能不生效。
- CGroups 相关配置(如
十、延伸知识点(非服务单元,但需了解)
- Socket 单元(.socket) :监听端口或 Unix 套接字,触发对应服务启动(如
dbus.socket
)。 - Target 单元(.target) :逻辑分组,用于组织多个服务(如
graphical.target
包含桌面环境相关服务)。 - Timer 单元(.timer) :定时任务,替代传统
cron
(如logrotate.timer
)。 - Mount 单元(.mount):管理文件系统挂载(如自动挂载 NFS 共享)。
总结:systemd 核心优势
- 并行启动:通过依赖关系分析,并行启动无依赖的服务,大幅缩短启动时间。
- 标准化配置:统一的单元文件格式,易于维护和迁移。
- 强大的管理工具链 :
systemctl
、journalctl
、systemd-analyze
等工具覆盖全生命周期管理。 - 资源精细化控制:通过 CGroups 实现 CPU、内存、进程数等资源的隔离与限制。