systemd控制服务启动顺序的核心是wants/requires与after/before组合使用:wants为弱依赖(失败不影响本服务),requires为强依赖(失败则本服务不启动),after/before仅控制时序而不保证就绪,需搭配target或条件指令确保真正可用。

systemd 控制服务启动顺序,核心在于单元文件中依赖与时序指令的组合使用,不是简单写个 After= 就能保证服务“真正就绪”。
理解 Wants 和 Requires 的区别
这两个字段都表达依赖,但行为不同:
- Wants= 是弱依赖:列出的服务会尝试启动,但即使失败或不存在,当前服务仍会继续启动
- Requires= 是强依赖:列出的服务必须成功启动并进入 active 状态,否则当前服务直接失败、不启动
例如,一个数据库服务若依赖本地存储挂载,用 Requires=local-fs.target 更稳妥;而只是希望日志服务顺带起来,用 Wants=syslog.service 更合适。
After/Before 只控制启动时机,不保证服务就绪
After=network.target 表示“在网络 target 启动之后才开始本服务”,但它不检查网络是否真正可用(比如 IP 配置完成、DNS 可解析)。实际中常见问题:
- 服务启动时网络接口刚 up,但 DHCP 还没返回地址
- 服务尝试连接远程 API,但防火墙规则尚未加载
解决办法是搭配更细粒度的 target 或自定义条件,比如:
- 用
After=network-online.target(需 network-manager 或 systemd-networkd 支持) - 在 service 中添加
ConditionPathExists=/run/systemd/network/online - 或用
Type=notify+sd_notify()让服务主动通知 systemd “我已就绪”
target 是组织启动逻辑的关键枢纽
systemd 不再按传统 runlevel 启动,而是靠 target 单元聚合一组服务。常见 target 包括:
- multi-user.target:默认多用户命令行环境,多数后台服务应在此 target 下启用
- network.target:仅表示基础网络子系统已加载,不等于网络可用
- network-online.target:表示网络已配置完成且可达(需额外支持)
- basic.target:基础系统服务就绪后触发,适合轻量级前置依赖
自定义服务若需在 SSH 启动前运行,可设 Before=sshd.service 并 Wants=sshd.service;若只想随系统一起拉起,WantedBy=multi-user.target 就足够。
修改后必须重载配置才能生效
编辑完 /etc/systemd/system/myapp.service 后,不能只 systemctl restart:
- 先运行
systemctl daemon-reload—— 让 systemd 重新读取所有 unit 文件 - 再用
systemctl enable myapp.service注册开机启动(如需) - 最后
systemctl start myapp测试启动逻辑
验证顺序是否符合预期,可用:systemctl list-dependencies --before myapp.service 查看哪些服务应在它之前启动systemctl list-dependencies --after myapp.service 查看哪些服务依赖它











