关于本文
本文参考了 systemd 官方手册,并整理了一套在 Ubuntu 中排查服务故障的操作步骤。验证状态:📘 已确认官方规范,目标 Ubuntu 实机未验证
文中将以读取为主的检查命令和修改状态的命令进行了明确的区分。
当 Ubuntu 中的服务无法启动时,切勿仅凭 systemctl status 做判断,按照 Unit 定义 → systemd 记录的状态 → 服务进程 → journal 日志的顺序结合查看,将更容易追踪到原因。比起一开始就反复重启,在保留故障时期的信息下进行调查要安全得多。
首先执行的检查命令
以下以服务名为 nginx 为例。
systemctl status nginx --no-pager systemctl is-active nginx systemctl is-enabled nginx journalctl -u nginx --no-pager -n 80
status 用于查看全局概览,is-active 用于查看当前状态,is-enabled 用于查看开机自启设置,journalctl 用于查看时间序列记录。
flowchart LR
A[Unit definition] --> B[systemd manager]
B --> C[service process]
B --> D[active / failed / inactive]
C --> E[stdout / stderr]
E --> F[journal]
D --> G[systemctl]
F --> H[journalctl]
active 与 enabled 是两码事
状态为 enabled 并不意味着它现在正在运行。
| 状态 | 含义 |
|---|---|
| active | 当前在 systemd 中处于 active 状态 |
| inactive | 当前不处于 active 状态 |
| failed | 启动或运行失败状态 |
| enabled | 已注册到开机等启动时的依赖关系中 |
| disabled | 未设置 enable |
例如,手动启动的服务即使处于 active 状态,也可能是 disabled。
flowchart TB
A[service] --> B{is-active}
A --> C{is-enabled}
B -->|active| D[現在動作中]
B -->|failed| E[失敗状態]
C -->|enabled| F[自動起動の設定あり]
C -->|disabled| G[自動起動の設定なし]
应该查看 status 的哪些内容
systemctl status nginx --no-pager
需要关注的重点如下。
Loaded:加载了哪个 Unit
Active:当前状态
Main PID:主进程
与 Result 或退出原因相关的提示
最近的 journal 日志摘要
由于仅看 status 的末尾可能不够全面,因此在发生故障时应转向 journalctl。
按时间顺序追踪 journal 日志
最近 80 行:
journalctl -u nginx --no-pager -n 80
限定当前引导(boot):
journalctl -u nginx -b --no-pager
限定时间范围:
journalctl -u nginx --since "30 minutes ago" --no-pager
比起“仅用 grep 过滤带有 error 字样的行”,阅读失败前后的几十行通常更能让人理清“读取配置 → 启动 → 失败”的整个流程。
查看 systemd 实际加载的 Unit
确认你以为编辑的文件与 systemd 实际使用的定义是否一致。
systemctl cat nginx
此外,若要从程序上查看 Unit 的加载来源等信息,也可以使用 systemctl show。
systemctl show nginx -p FragmentPath -p DropInPaths -p ActiveState -p SubState -p Result -p ExecMainStatus
通过这些方法,可以更容易地排查诸如“其他 drop-in 配置先生效了”或“并非预期的 Unit 文件”之类的问题。
仅在修改 Unit 时才考虑使用 daemon-reload
修改了 Unit 文件或 drop-in 后,需要让 systemd 管理器重新加载定义。
sudo systemctl daemon-reload
daemon-reload 并不是重启服务进程本身的命令。
flowchart LR
A[Unit fileを変更] --> B[daemon-reload]
B --> C[systemd managerが定義を再読込]
C --> D{process再起動も必要?}
D -->|Yes| E[restart等を検討]
D -->|No| F[定義確認で終了]
不要形成“既然修改了配置文件,那就先 daemon-reload 然后再 restart”的僵化步骤,而应根据你究竟修改了什么来做决定。
为什么不应首先选择重启(restart)
虽然重启可以暂时修复某些故障,但在调查原因时这可能会导致丢失关键信息。
推荐的排查顺序如下。
flowchart TB
A[障害を検知] --> B[status]
B --> C[journalctl]
C --> D[systemctl cat / show]
D --> E[アプリ固有のconfig test]
E --> F{原因を特定}
F -->|No| G[依存関係・port・権限等を追加確認]
F -->|Yes| H[必要な変更]
H --> I[必要ならreload/restart]
I --> J[再度statusとjournalで確認]
将“服务自身的验证”(如 Nginx 的 nginx -t,或 PHP-FPM 根据版本和配置执行的 config test)与 systemd 调查结合起来。
如果只看 systemd 仍无法找到原因
systemd 负责管理进程,但它并不理解应用程序特有的配置错误。
例如,以下内容也需要单独进行检查。
配置文件语法
端口冲突
文件权限
EnvironmentFile 的值
运行用户
依赖关系
应用程序专属日志
systemctl 并非“能够解决一切问题的命令”,它只是操作系统服务管理的入口。
总结
status、is-active、is-enabled 的职责各不相同
通过 journalctl 追踪直到失败的时间线
使用 systemctl cat / show 确认实际的 Unit 定义
区分对待 Unit 修改后的 daemon-reload 与进程重启
在重启之前,先收集故障时的信息
将 systemd 调查与应用专属的配置测试结合起来
官方资料与一手信息
systemd — systemctl
https://www.freedesktop.org/software/systemd/man/latest/systemctl.html
systemd — journalctl
https://www.freedesktop.org/software/systemd/man/latest/journalctl.html
systemd — systemd.unit
https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
