0%

systemd 服务一直重启时,看 Result 和 NRestarts

单元设了 Restart= 之后,进程一退出就会被拉起来。看起来像「起不来」,状态却可能在 activating 和 active 之间来回。先分清是进程自己退出,还是启动步骤就失败,再看是不是已经撞上启动次数限制。日志仍用 journalctl -u。

1
2
systemctl status 单元名.service --no-pager
systemctl show 单元名.service -p ActiveState,SubState,Result,NRestarts,Restart,ExecMainStatus,ExecMainCode,StartLimitBurst,StartLimitIntervalUSec

NRestarts 一直增加,说明 systemd 在反复拉起。Restart=always 时,进程正常退出(代码 0)也会再启动。Restart=on-failure 只在非 0 退出、被信号杀死或超时后再启动。

Result= 是上一次的结果:

  • exit-code:进程退出码不是 0,具体码在 ExecMainStatus
  • signal:被信号杀掉
  • timeout:超过 TimeoutStartSec 还没就绪
  • start-limit-hit:在 StartLimitIntervalUSec 这段时间里,失败次数达到 StartLimitBurst,systemd 停止再拉

默认突发次数很小,一个起不来的服务常常几秒后就变成 start-limit-hit,之后不再重启。这时 systemctl start 会马上失败。原因还在 journal 前一次的 exit-code 或 timeout 里,不在 start-limit-hit 这一句里。

改完单元或程序之后,清掉失败计数再启动:

1
2
sudo systemctl reset-failed 单元名.service
sudo systemctl start 单元名.service

reset-failed 只清状态,不修配置。TimeoutStartSec 太短时,把就绪时间拉长之前,服务会一直以 timeout 进入下一轮重启。