如何配置 systemd 服务依赖 After 和 Requires 区别是什么

文章导读
systemd 中 After 仅控制启动时序,Requires 定义强依赖关系;若依赖服务启动失败,Requires 会导致当前服务停止,而 After 单独使用不触发依赖服务启动。配置时通常需组合使用 After 与 Requires(或 Wants),避免仅写 After 导致依赖未就绪。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

systemd 中 After 仅控制启动时序,Requires 定义强依赖关系;若依赖服务启动失败,Requires 会导致当前服务停止,而 After 单独使用不触发依赖服务启动。配置时通常需组合使用 After 与 Requires(或 Wants),避免仅写 After 导致依赖未就绪。

先说结论:After 决定启动先后顺序,Requires 决定依赖失败是否阻断当前服务,两者语义不同且需配合使用。

  • 适合:需要严格控制服务启动顺序且依赖服务必须可用的场景。
  • 先准备:确认依赖服务的单元名称(如 redis.service)及是否开机自启。
  • 验收:修改配置后执行 daemon-reload 并通过 status 命令验证依赖链路。

命令速用版

若需快速修改现有服务依赖,建议使用 systemctl edit 命令创建覆盖配置,避免直接修改原始文件。

sudo systemctl edit myapp.service

在编辑器中输入以下内容后保存退出:

[Unit]
After=network-online.target
Wants=network-online.target

保存后执行以下命令使配置生效:

sudo systemctl daemon-reload
sudo systemctl restart myapp.service

为什么会这样

After 和 Requires 的核心区别在于是否触发依赖启动及是否检查依赖状态。

After 仅表示时间上的先后,即“我在它之后启动”,但不保证“它”一定会启动;若未配合 Wants 或 Requires,systemd 可能并行处理导致依赖未就绪。Requires 表示逻辑强依赖,若依赖单元启动失败或未激活,当前服务将直接进入 failed 状态。实际场景中,绝大多数非关键依赖建议使用 Wants 配合 After,仅当依赖服务不可用会导致当前服务无法运行时才使用 Requires。

分步处理

第一步:定位服务单元文件路径。

优先在/etc/systemd/system/目录下查找自定义配置,若不存在则查看/usr/lib/systemd/system/下的默认配置。

第二步:编辑[Unit]段配置。

打开服务文件,在[Unit]部分添加依赖声明。若依赖网络就绪,使用 Wants=network-online.target 配合 After=network-online.target;若依赖数据库,使用 Requires=postgresql.service 配合 After=postgresql.service。

第三步:重载配置并重启服务。

执行 systemctl daemon-reload 重新加载单元定义,随后重启服务使依赖关系生效。

怎么验证是否生效

使用 systemctl status 查看服务状态及依赖链路。

执行 systemctl status myapp.service,观察 Active 状态是否为 active (running),并检查日志中是否有依赖相关的报错。

使用 systemd-analyze critical-chain 分析启动关键路径。

如何配置 systemd 服务依赖 After 和 Requires 区别是什么

执行 systemd-analyze critical-chain myapp.service,确认依赖单元是否出现在链路中且耗时正常。

查看系统日志确认依赖顺序。

执行 journalctl -u myapp.service -u dependency.service,对比两个服务的启动时间戳,确认当前服务确实在依赖服务之后启动。

常见坑

仅配置 After 而未配置 Wants 或 Requires。

这会导致依赖服务未被激活,当前服务虽在时间上滞后但实际依赖资源不可用,引发连接拒绝错误。

对非关键服务滥用 Requires。

若依赖服务不稳定,Requires 会导致当前服务随之下线,建议改用 Wants 降低耦合。

混淆 network.target 与 network-online.target。

network.target 仅表示网络管理已启动,不保证网卡已配置 IP;需联网的服务应依赖 network-online.target。

循环依赖导致加载失败。

若 A 依赖 B 且 B 依赖 A,systemd 将拒绝加载单元文件并报错 dependency cycle。

常见问题

只写 After= 不写 Requires= 会有什么后果?

依赖服务可能根本不会启动,当前服务会因资源不可用而失败。

Wants 和 Requires 应该选哪个?

非关键依赖选 Wants,关键依赖选 Requires,绝大多数场景推荐使用 Wants 以避免级联失败。

配置修改后为什么没生效?

修改单元文件后必须执行 systemctl daemon-reload 重新加载配置。

参考来源

  • Linux systemd 服务依赖关系解析
  • Linux systemd 启动单元依赖关系配置与优化指南
  • Linux 服务启动顺序如何控制?
  • Linux 服务启动顺序配置实战
  • Linux 如何配置 systemd 服务依赖关系