Linux 服务依赖关系分析与优化

3次阅读

用 systemctl list-dependencies –all 和 –reverse 查清正向依赖与反向依赖,结合 systemd-analyze dot 生成图形化依赖图,辅以 systemctl status、journalctl 和 systemd-analyze blame 定位启动瓶颈。

Linux 服务依赖关系分析与优化

systemd 服务依赖图怎么看

直接用 systemctl list-dependencies 最快,但默认只展开一层,容易误判真实启动顺序。加 --all--reverse 才能看清谁在依赖你、谁被你拖住。

  • systemctl list-dependencies --all nginx.service:列出 nginx 所有正向依赖(比如 network.targetsyslog.socket
  • systemctl list-dependencies --all --reverse nginx.service:查哪些服务等 nginx 启动完才动(比如 prometheus-node-exporter.service
  • 注意 Wants 不等于强依赖,Requires + After 才真正影响启动顺序
  • 图形化导出靠 systemd-analyze dot,但输出是 dot 格式,得用 dot -Tpng 转,别直接双击打开

服务启动卡在某个 unit 怎么定位

不是所有“卡住”都真卡了,很多是超时后被 systemd 主动终止,日志里只留一句 Timed out waiting for device,根本看不出等谁。

  • 先跑 systemctl status <em>service-name</em>,重点看 Active: 和 Loaded: 行,确认是不是 failed 或 activating(而非 inactive)
  • 再查 journalctl -u <em>service-name</em> --since "1 hour ago",过滤 Failed to starttimed out
  • 如果日志里反复出现 ConditionPathExists=/etc/ssl/private/key.pem 失败,说明服务在等文件就绪,但没设 StartLimitIntervalSec=0,重试被限流了
  • systemd-analyze blame 看耗时最长的 unit,常是 dev-disk-byx2duuid-xxx.device 这类设备单元——实际是磁盘挂载慢或 fstab 配错

想删掉无用依赖,但删完服务起不来

Wants= 安全,删 Requires= 或改 After= 很可能让服务启动失败,因为 systemd 不会校验语义合理性,只按字面执行。

  • 修改前先备份:cp /usr/lib/systemd/system/foo.service /etc/systemd/system/foo.service(覆盖优先级更高)
  • Requires=bar.service 前,先确认 bar 是否提供关键 socket 或路径,比如删掉 Requires=sshd.socket 会导致 sshd 启动后没监听端口
  • After=multi-user.target 改成 After=network-online.target 是常见优化,但得确保服务真需要网络就绪,否则反而拖慢启动
  • 改完必须运行 systemctl daemon-reload,否则 systemctl cat 还显示旧内容

自定义 service 如何写不踩坑的依赖

新手爱写 After=network.target,结果发现网络接口还没配好 IP 就启动了;老手知道要区分 “网络子系统可用” 和 “网络连通可用”。

  • 需要 DNS 解析或外网访问?用 After=network-online.target + Wants=network-online.target,但得确认 systemd-networkd-wait-online.service 已启用
  • 只读本地文件或监听 localhost?After=local-fs.target 足够,别硬拉 network.target
  • 避免循环依赖:A Wants=B 且 B Wants=A 会导致两者都启动失败,systemd-analyze verify 可提前报错
  • Type=notifyType=simple 更准,但程序必须调用 sd_notify("READY=1"),否则 systemd 一直等超时

依赖关系不是越细越好,关键是匹配服务的真实前置条件。很多人花半天画依赖图,却忘了检查 /etc/fstab 里一个挂载点超时设置是 0,这才是真正卡住 90 秒的原因。

text=ZqhQzanResources