systemd 教程 / 服务管理(systemctl)
服务管理(systemctl)
一、systemctl 简介
systemctl 是 systemd 的主命令行工具,用于管理系统服务、查看服务状态、控制启动行为等。几乎所有 systemd 操作都通过 systemctl 完成。
# 基本语法
systemctl [OPTIONS] COMMAND [UNIT...]
二、服务生命周期操作
2.1 启动、停止、重启、重载
# 启动服务
systemctl start nginx.service
# 停止服务
systemctl stop nginx.service
# 重启服务(先 stop 再 start)
systemctl restart nginx.service
# 重新加载配置(不中断服务,要求服务支持 reload)
systemctl reload nginx.service
# 先 reload,如果不支持则 restart
systemctl reload-or-restart nginx.service
# 同上,但尝试 reload 失败时也 restart
systemctl try-reload-or-restart nginx.service
💡 提示:服务名可以省略 .service 后缀,systemctl start nginx 等同于 systemctl start nginx.service。但建议写全名以避免歧义。
2.2 restart vs reload
| 操作 | 行为 | 适用场景 |
|---|---|---|
restart | 完全停止再启动,PID 改变 | 修改了需要重启才能生效的配置 |
reload | 发送信号重新加载配置,PID 不变 | 修改了支持热加载的配置(如 Nginx) |
reload-or-restart | 优先 reload,不支持则 restart | 不确定服务是否支持 reload |
try-reload-or-restart | 尝试 reload,失败则 restart | 更安全的选择 |
2.3 查看服务状态
# 查看服务详细状态
systemctl status nginx.service
输出示例:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-05-11 10:30:15 CST; 2h ago
Docs: man:nginx(8)
Process: 12345 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; (code=exited, status=0/SUCCESS)
Main PID: 12346 (nginx)
Tasks: 3 (limit: 4915)
Memory: 12.5M
CPU: 1.234s
CGroup: /system.slice/nginx.service
├─12346 "nginx: master process /usr/sbin/nginx -g daemon on;"
├─12347 "nginx: worker process"
└─12348 "nginx: worker process"
May 11 10:30:15 server systemd[1]: Starting A high performance web server...
May 11 10:30:15 server systemd[1]: Started A high performance web server.
状态字段含义:
| 字段 | 说明 |
|---|---|
Loaded | Unit 文件路径及是否 enabled |
Active | 当前状态(active/inactive/failed) |
Main PID | 主进程 ID |
Tasks | CGroup 中的进程数及限制 |
Memory | 内存使用量 |
CGroup | CGroup 树中的进程列表 |
2.4 服务状态一览
| 状态 | 含义 |
|---|---|
active (running) | 正在运行 |
active (exited) | 一次性任务已完成(Type=oneshot) |
active (waiting) | 等待事件(Type=idle) |
inactive (dead) | 未运行 |
failed | 启动失败或运行中崩溃 |
activating (start) | 正在启动 |
deactivating (stop) | 正在停止 |
三、开机自启管理
3.1 启用与禁用
# 设置开机自启
systemctl enable nginx.service
# 取消开机自启
systemctl disable nginx.service
# 启用并立即启动
systemctl enable --now nginx.service
# 禁用并立即停止
systemctl disable --now nginx.service
3.2 enable 的原理
# 查看 enable 创建的符号链接
systemctl enable nginx.service 2>&1
输出示例:
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.
enable 实际上是在对应的 Target 的 .wants 目录下创建指向 Unit 文件的符号链接。
# 查看符号链接
ls -la /etc/systemd/system/multi-user.target.wants/
3.3 查看启用状态
# 查看所有 Unit 文件的启用状态
systemctl list-unit-files
# 过滤特定状态
systemctl list-unit-files --state=enabled
systemctl list-unit-files --state=disabled
systemctl list-unit-files --state=masked
# 查看特定 Unit
systemctl is-enabled nginx.service
输出可能为:
| 输出 | 含义 |
|---|---|
enabled | 已启用(符号链接存在) |
disabled | 未启用 |
static | 不可直接启用(被其他 Unit 依赖) |
masked | 已屏蔽(无法启动) |
generated | 由生成器创建 |
indirect | 通过 Also= 间接启用 |
enabled-runtime | 运行时启用(重启后失效) |
四、列出所有服务
# 列出所有已加载的 Unit
systemctl list-units
# 只列出 service 类型
systemctl list-units --type=service
# 列出所有(包括未加载的)
systemctl list-units --all
# 列出 Unit 文件
systemctl list-unit-files --type=service
# 按状态过滤
systemctl list-units --state=failed
# 显示所有失败的服务
systemctl --failed
常用过滤参数:
| 参数 | 说明 |
|---|---|
--type=TYPE | 按 Unit 类型过滤 |
--state=STATE | 按状态过滤 |
--all | 显示所有(包括 inactive) |
--no-pager | 不使用分页器 |
--plain | 简洁输出 |
--no-legend | 不显示表头 |
五、服务依赖关系
# 查看正向依赖(启动时需要什么)
systemctl list-dependencies nginx.service
# 查看反向依赖(谁依赖此服务)
systemctl list-dependencies nginx.service --reverse
# 只显示当前 active 的
systemctl list-dependencies nginx.service --state=active
# 显示所有层级
systemctl list-dependencies nginx.service --all
# 显示指定 Target 的依赖树
systemctl list-dependencies multi-user.target
输出示例:
nginx.service
● ├─system.slice
● ├─sysinit.target
● │ ├─apparmor.service
● │ ├─keyboard-setup.service
● │ ├─systemd-journal-flush.service
● │ ├─systemd-modules-load.service
● │ └─...
● └─network.target
● └─NetworkManager.service
六、掩码(Mask/Unmask)
# 屏蔽服务(完全禁止启动,比 disable 更强)
systemctl mask nginx.service
# 取消屏蔽
systemctl unmask nginx.service
mask vs disable 对比
| 操作 | 效果 | 手动 start | enable |
|---|---|---|---|
disable | 移除自启链接 | ✅ 可以 | ✅ 可以 |
mask | 创建指向 /dev/null 的链接 | ❌ 不可以 | ❌ 不可以 |
# 查看被 mask 的符号链接
ls -la /etc/systemd/system/nginx.service
# 输出:nginx.service -> /dev/null
⚠️ 注意:mask 是最强的禁用手段。被 mask 的服务连 systemctl start 都无法启动,必须先 unmask。适用于确认某服务绝不应该运行的场景。
七、失败服务处理
# 查看所有失败的服务
systemctl --failed
# 查看特定服务的失败详情
systemctl status myapp.service
# 查看服务日志
journalctl -u myapp.service -n 50
# 重置失败状态
systemctl reset-failed myapp.service
# 重置所有失败状态
systemctl reset-failed
失败排查流程
# 1. 查看状态和最近日志
systemctl status myapp.service
# 2. 查看详细日志
journalctl -u myapp.service --since "10 minutes ago"
# 3. 检查 Unit 文件语法
systemd-analyze verify /etc/systemd/system/myapp.service
# 4. 检查安全限制
systemd-analyze security myapp.service
# 5. 尝试手动启动以捕获错误
sudo -u myappuser /usr/local/bin/myapp
# 6. 修复后重置状态并重启
systemctl reset-failed myapp.service
systemctl restart myapp.service
八、批量操作
# 同时操作多个服务
systemctl start nginx.service php-fpm.service redis.service
# 启用多个服务
systemctl enable nginx.service php-fpm.service
# 重启多个服务
systemctl restart nginx php-fpm redis
# 使用通配符(systemctl 支持 glob 模式)
systemctl status 'web*'
# 重启某个 Slice 下的所有服务
systemctl restart user-1000.slice
批量管理脚本示例
#!/bin/bash
# restart-all-webapp.sh — 重启所有 web 相关服务
services=(
nginx.service
php8.2-fpm.service
redis-server.service
myapp-worker.service
)
for svc in "${services[@]}"; do
echo "Restarting ${svc}..."
if systemctl restart "${svc}"; then
echo " ✓ ${svc} restarted successfully"
else
echo " ✗ ${svc} failed to restart"
fi
done
# 检查是否有失败的服务
failed=$(systemctl --failed --no-legend | wc -l)
if [ "$failed" -gt 0 ]; then
echo "⚠ ${failed} service(s) in failed state"
systemctl --failed --no-pager
fi
九、systemctl 常用命令速查表
服务控制
| 操作 | 命令 |
|---|---|
| 启动 | systemctl start <unit> |
| 停止 | systemctl stop <unit> |
| 重启 | systemctl restart <unit> |
| 重载 | systemctl reload <unit> |
| 重载或重启 | systemctl reload-or-restart <unit> |
| 查看状态 | systemctl status <unit> |
| 检查是否运行 | systemctl is-active <unit> |
| 检查是否失败 | systemctl is-failed <unit> |
启用/禁用
| 操作 | 命令 |
|---|---|
| 设为自启 | systemctl enable <unit> |
| 取消自启 | systemctl disable <unit> |
| 启用并启动 | systemctl enable --now <unit> |
| 检查是否启用 | systemctl is-enabled <unit> |
| 屏蔽 | systemctl mask <unit> |
| 取消屏蔽 | systemctl unmask <unit> |
列表查询
| 操作 | 命令 |
|---|---|
| 列出活动 Unit | systemctl list-units |
| 列出 Unit 文件 | systemctl list-unit-files |
| 列出失败 Unit | systemctl --failed |
| 查看依赖 | systemctl list-dependencies <unit> |
| 查看反向依赖 | systemctl list-dependencies <unit> --reverse |
系统操作
| 操作 | 命令 |
|---|---|
| 关机 | systemctl poweroff |
| 重启 | systemctl reboot |
| 挂起 | systemctl suspend |
| 休眠 | systemctl hibernate |
| 进入救援模式 | systemctl rescue |
| 进入紧急模式 | systemctl emergency |
| 重载 systemd | systemctl daemon-reload |
| 设为默认目标 | systemctl set-default multi-user.target |
| 切换目标 | systemctl isolate graphical.target |
十、生产场景
场景 1:零停机部署
# 对于支持 reload 的服务(如 Nginx),零停机更新配置
systemctl reload nginx.service
# 对于支持 graceful restart 的服务
# ExecReload=/bin/kill -HUP $MAINPID
systemctl reload myapp.service
场景 2:服务自动重启
# 确保关键服务在崩溃后自动重启
# 在 Unit 文件中配置:
# [Service]
# Restart=on-failure
# RestartSec=5
# StartLimitBurst=3
# StartLimitIntervalSec=60
# 手动触发重启(例如部署新版本后)
systemctl restart myapp.service
# 验证服务正在运行
systemctl is-active myapp.service && echo "OK" || echo "FAIL"
场景 3:维护模式下停止所有 Web 服务
#!/bin/bash
# maintenance.sh — 进入维护模式
echo "进入维护模式..."
systemctl stop nginx.service
systemctl mask nginx.service # 防止被意外启动
# 执行维护操作...
echo "维护中... 按 Enter 继续"
read
# 退出维护模式
echo "退出维护模式..."
systemctl unmask nginx.service
systemctl start nginx.service
echo "服务已恢复"