应使用network-online.target而非network.target,因后者仅表示网络服务进程启动,不保证ip配置完成或网络可达;需启用systemd-networkd-wait-online.service或networkmanager-wait-online.service,并在服务单元中配置wants=network-online.target和after=network-online.target。

要让 systemd 服务在网络真正就绪后才启动,不能只写 After=network.target——它只表示“网络服务进程已启动”,不保证网卡已配好 IP、路由可达或 DNS 可用。必须等待 network-online.target,它是 systemd 中代表“网络已实际可用”的标准信号。
启用并确认 network-online.target 可达
这个 target 本身不会自动就绪,它依赖后台服务来检测网络状态:
- 如果系统使用 systemd-networkd(如 Debian 12+/Ubuntu 22.04+ 默认),运行:
sudo systemctl enable --now systemd-networkd-wait-online.service - 如果使用 NetworkManager(如 RHEL/CentOS/Fedora/Ubuntu 桌面版),运行:
sudo systemctl enable --now NetworkManager-wait-online.service - 验证是否生效:
systemctl is-active network-online.target—— 正常应返回active;若超时返回inactive,说明 wait-online 服务未启用或配置异常
在服务单元中正确声明依赖
编辑你的服务文件(推荐放在 /etc/systemd/system/myapp.service),在 [Unit] 段添加:
-
Wants=network-online.target:表达“希望网络在线” -
After=network-online.target:确保启动顺序在它之后 - 避免仅写
Requires=network-online.target—— 若网络检测失败,会导致服务完全无法启动,过于刚性
完整示例:
[Unit]Description=My API Server
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myapi
Restart=on-failure
[Install]
WantedBy=multi-user.target
针对特定 IP 或网卡的精准等待(进阶场景)
当服务必须绑定到某个固定 IP(如 192.168.5.100)才能工作时,network-online.target 仍可能不够——它不保证该 IP 已分配到指定网卡。
- 若使用 systemd-networkd 管理网络:在服务中绑定对应动态单元,例如
BindsTo=systemd-networkd@eth0.serviceAfter=systemd-networkd@eth0.service
(前提是/etc/systemd/network/10-eth0.network已配置该 IP) - 通用兼容方式:用
ExecStartPre轮询检查 IP 就绪ExecStartPre=/bin/sh -c 'timeout 60 sh -c "while ! ip -4 addr show dev eth0 | grep -q \"inet 192.168.5.100/\"; do sleep 2; done" || exit 1'
常见错误排查要点
- 改完服务文件后,**必须执行**
sudo systemctl daemon-reload,否则修改不生效 - 检查服务是否真被启用:
systemctl is-enabled myapp.service - 查看启动卡点:
systemctl status myapp.service和journalctl -u myapp.service -n 50 - 确认依赖链是否完整:
systemctl list-dependencies --reverse myapp.service - 避免在自定义 unit 中设置
DefaultDependencies=no—— 这会切断与network-online.target的默认关联











