1.5.4 自启动配置与依赖关系管理
自启动配置与依赖关系管理的核心目标是让关键服务在系统启动时可靠、有序地拉起,并在故障场景下具备可控的恢复行为。以 systemd 为例,启动策略主要通过 unit 文件中的依赖与顺序关系实现,包括 Requires/Wants、After/Before、BindsTo/PartOf 等指令。Requires 表示强依赖,依赖单元失败会导致当前单元失败;Wants 为弱依赖,仅尝试拉起;After/Before 只影响顺序不构成依赖。实践中建议将“是否必须”与“启动顺序”拆分配置,避免误用 After 造成启动失败不易排查。
原理草图(服务依赖与顺序):
自启动配置方式与示例#
启用服务会生成到 target 的符号链接,完成自启动绑定:
# 查看服务是否启用
systemctl is-enabled nginx.service
# 启用并设置为开机自启(默认挂到 multi-user.target)
systemctl enable nginx.service
# 禁用自启动
systemctl disable nginx.service
自定义服务示例(以简单应用为例):
- 单元文件路径:/etc/systemd/system/demo-app.service
[Unit]
Description=Demo App Service
Requires=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/demo-app --port=8080 --config=/etc/demo-app/config.yml
ExecStartPre=/usr/local/bin/demo-app --check-config /etc/demo-app/config.yml
Restart=on-failure
RestartSec=3
StartLimitIntervalSec=60
StartLimitBurst=5
[Install]
WantedBy=multi-user.target
生效与启用:
# 重新加载 unit 文件
systemctl daemon-reload
# 启动服务并设置为自启动
systemctl start demo-app.service
systemctl enable demo-app.service
# 验证状态
systemctl status demo-app.service -l
依赖关系配置与命令解释#
常用指令与作用:
- Requires=:强依赖,依赖失败则当前失败
- Wants=:弱依赖,仅尝试启动
- After= / Before=:顺序控制,不构成依赖
- BindsTo=:绑定依赖,依赖停止会停止当前
- PartOf=:联动停止/重启
依赖树查看:
# 查看服务依赖树
systemctl list-dependencies demo-app.service
# 查看目标 target 下的所有服务
systemctl list-dependencies multi-user.target
典型场景:数据库与代理绑定#
当代理必须与数据库同生命周期:
# /etc/systemd/system/proxy.service
[Unit]
Description=DB Proxy
BindsTo=db.service
After=db.service
[Service]
ExecStart=/usr/local/bin/db-proxy --config=/etc/db-proxy.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
排错流程与命令示例#
启动失败排查:
# 查看最近启动日志
journalctl -u demo-app.service -n 100 --no-pager
# 查看失败原因与退出码
systemctl status demo-app.service -l
# 查看 unit 文件最终合并结果(含 drop-in)
systemctl cat demo-app.service
常见问题与处理:
- 网络未就绪导致失败
解决:改用 network-online.target,并确保 NetworkManager-wait-online.service 或 systemd-networkd-wait-online.service 已启用。
systemctl enable NetworkManager-wait-online.service
- 频繁重启造成限制
调整StartLimitIntervalSec、StartLimitBurst或临时清理计数:
systemctl reset-failed demo-app.service
练习#
- 编写一个自定义服务
hello.service,执行/usr/local/bin/hello.sh,要求开机自启并在失败时自动重启。 - 配置
hello.service依赖network-online.target,并确保网络就绪再启动。 - 使用
systemctl list-dependencies验证依赖树是否包含network-online.target。 - 通过故意让脚本退出码为 1,观察
Restart=on-failure的效果并用journalctl分析日志。