VPS服务频繁重启,journalctl中出现 WATCHDOG=triggered、watchdog timeout 或类似提示时,问题可能来自 systemd 的服务看门狗,而不是应用主动崩溃。systemd 会根据服务声明的 WatchdogSec 等待心跳;如果进程未按时发送,systemd可能判定服务失去响应并执行 Restart=。先确认重启触发者,再决定是否调整阈值。
区分Restart策略和Watchdog触发
systemctl status <service> --no-pager
systemctl show <service> --property=Restart,RestartUSec,WatchdogUSec,NotifyAccess,MainPID
journalctl -u <service> -b --no-pager | tail -n 200
Restart=always/on-failure表示服务退出后如何重启,WatchdogSec则决定是否因心跳超时被判定失败。日志中应记录退出码、信号、触发时间和上一次心跳时间;不要只看“服务自动恢复”就认为根因解决。
确认应用是否真的支持sd_notify
systemd看门狗通常依赖服务通过 sd_notify 发送READY、WATCHDOG和STATUS消息。若程序未编译支持、环境变量未传递、NotifyAccess范围不正确,设置WatchdogSec后可能立即误重启。检查服务文档、unit文件和进程环境,确认心跳由正确的主进程或允许的子进程发送。
把启动阶段和运行阶段分开
应用启动时加载模型、恢复索引、连接数据库或执行迁移,可能暂时无法发送心跳。应使用 Type=notify、合理的启动超时和READY通知表达“已就绪”,而不是把WatchdogSec调得很大掩盖启动阻塞。运行阶段若心跳停止,再结合CPU限流、I/O等待、锁竞争、网络依赖和进程日志定位。
低风险调参顺序
- 先保存当前unit、环境文件和服务日志。
- 确认应用心跳周期与WatchdogSec有明确余量。
- 在维护窗口临时放宽阈值或关闭看门狗做对照,不要长期关闭监控。
- 修复阻塞点或心跳线程,再恢复看门狗并观察完整业务周期。
若服务属于容器或多进程模型,还要确认systemd监控的PID与实际发送心跳的进程一致。不要用外部脚本伪造心跳,否则会让systemd认为服务健康而掩盖真实阻塞。
验收看重“少重启且业务正常”
systemctl is-active <service>
systemctl show <service> --property=NRestarts,ExecMainStatus,StatusText
journalctl -u <service> --since "30 min ago" --no-pager
同时观察业务健康检查、P95延迟、错误率、CPU throttling、I/O PSI和依赖服务状态。重启次数下降但请求仍超时,说明看门狗只是症状层,根因仍未修复。
Watchdog的价值在于快速隔离失去响应的服务,但前提是心跳实现、启动模型和资源预算一致。先确认触发链,再做小步调参并保留回滚,才能避免“自动重启掩盖故障”。






