← 中文资源

简体中文版本

加固 systemd 服务对抗崩溃与重启

为 systemd 单元设置 Restart、看门狗与资源限制,让崩溃自愈、挂死被杀、启动顺序显式声明。

阅读英文原文

目标

systemd 本身就内置了多数人在包装脚本里重复实现的自治逻辑:重启策略带退避地救活崩溃进程,看门狗杀掉不再证明活性的进程,资源上限兜住泄漏,单元排序修掉启动竞态。把这些写进 unit 文件,就把一堆没说出口的希望换成经过测试的生命周期契约。

步骤要点

  1. 配 Restart=on-failure、RestartSec=5、StartLimitIntervalSec=300、StartLimitBurst=5:崩溃 5 秒复活,5 分钟内超 5 次则停止反复拉起。
  2. 加 WatchdogSec=30 并让应用通过 sd_notify 定期喂狗,30 秒无声即杀掉重启,覆盖“活着但不干活”。
  3. After/Wants network-online.target 并 enable,重启后服务可靠回归,不再抢在网络之前启动。
  4. MemoryMax/LimitNOFILE/CPUWeight 圈定资源,泄漏只烧自己的额度并按流程被 OOM。
  5. 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