目标
systemd 本身就内置了多数人在包装脚本里重复实现的自治逻辑:重启策略带退避地救活崩溃进程,看门狗杀掉不再证明活性的进程,资源上限兜住泄漏,单元排序修掉启动竞态。把这些写进 unit 文件,就把一堆没说出口的希望换成经过测试的生命周期契约。
步骤要点
- 配 Restart=on-failure、RestartSec=5、StartLimitIntervalSec=300、StartLimitBurst=5:崩溃 5 秒复活,5 分钟内超 5 次则停止反复拉起。
- 加 WatchdogSec=30 并让应用通过 sd_notify 定期喂狗,30 秒无声即杀掉重启,覆盖“活着但不干活”。
- After/Wants network-online.target 并 enable,重启后服务可靠回归,不再抢在网络之前启动。
- MemoryMax/LimitNOFILE/CPUWeight 圈定资源,泄漏只烧自己的额度并按流程被 OOM。
- daemon-reload 后故意 systemctl kill 验证 8 秒内自愈,is-active 复核终态。
排错提示
进入 failed 状态说明撞到启动上限,先查崩溃根因而不是抬高限额把问题藏更久;看门狗误杀健康服务是喂狗间隔太粗,要小于 WatchdogSec 的一半且喂狗线程绝不阻塞在 I/O 上;手动能起、重启后起不来是排序隐式所致,补 After/Wants 并用 journalctl -b 查早启动日志。
适用边界
重启策略治的是症状,每晚重启的服务依然是坏的,值得根因修复;看门狗需要应用侧配合 sd_notify 才能工作。
代码示例
[Service]
Type=exec
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=300
StartLimitBurst=5
WatchdogSec=30
MemoryMax=1500M
[Unit]
After=network-online.target
Wants=network-online.target