应使用Wants=network-online.target与After=network-online.target组合,并启用对应wait-online服务(如systemd-networkd-wait-online.service);避免仅用After=network.target或Requires=network-online.target等错误写法。

要让 systemd 服务在真正有网络连接后才启动,不能只依赖 network.target 或 network-online.target 就完事——因为它们的语义和实际行为容易被误解。关键在于区分“网络接口已配置”和“网络可达”。
用 Wants=network-online.target + After=network-online.target
这是最常用也最推荐的基础写法,但必须配合网络管理器(如 systemd-networkd 或 NetworkManager)正确启用 systemd-networkd-wait-online.service 或 NetworkManager-wait-online.service:
-
Wants=network-online.target表示“我需要这个目标被激活”,不强制阻塞,但配合After才生效 -
After=network-online.target确保服务在该目标**完成激活后**才开始启动 - 注意:
network-online.target本身不会自己就绪,它依赖底层的 wait-online 服务来判断网络是否真正可用(比如能 ping 通网关或 DNS)
确认 wait-online 服务已启用并工作
不同网络管理器启用方式不同,漏掉这步会导致 network-online.target 立即就绪(假成功):
- 用 systemd-networkd:运行
sudo systemctl enable systemd-networkd-wait-online.service - 用 NetworkManager:运行
sudo systemctl enable NetworkManager-wait-online.service - 验证是否生效:
systemctl is-active systemd-networkd-wait-online(或对应服务),应为active;再查systemctl show network-online.target | grep ActiveState,应为active且不是瞬间变 active
对强网络依赖服务,加超时和重试更稳妥
即使用了 network-online.target,某些服务(如需访问特定 API 或内部 DNS)仍可能因网络策略、防火墙或服务端延迟而失败。可在 service 文件中增强鲁棒性:
-
StartLimitIntervalSec=60和StartLimitBurst=3防止反复崩溃刷日志 -
Restart=on-failure+RestartSec=10让服务自动重试 - 若逻辑允许,服务自身检查网络连通性(例如启动脚本里
until ping -c1 example.com &>/dev/null; do sleep 2; done),比纯依赖 systemd 更可控
避免常见错误写法
这些写法看似合理,实则无效或危险:
- 只写
After=network.target:它只表示“网络服务已启动”,但接口可能还没配 IP、DHCP 没完成,不保证能上网 - 写
Requires=network-online.target:过于严格,如果 wait-online 失败(比如没网线),你的服务会直接无法启动,而非等待或重试 - 在 service 中用
ExecStartPre=/usr/bin/sleep 10:硬编码延时不可靠,快网慢网都一样等,既不精准也不优雅










