
需结合 journalctl 查日志确认频繁重启:用 journalctl -u -n 100 --no-pager -o json-pretty 找 exited/Killed/Segmentation fault;OOM 要查 dmesg -T | grep "killed process";依赖问题看 systemctl cat 中 Requires/BindsTo 缺失;节流机制需检查 StartLimitIntervalSec 和 StartLimitBurst。
服务频繁重启时,systemctl status 只显示最终状态,容易误判为“已启动”,实际可能刚崩溃又拉起。必须结合日志看完整生命周期。
journalctl -u -n 100 --no-pager 查最近 100 行,重点找 exited with code、Killed、Segmentation fault 等关键词-o json-pretty 可看清每条日志的时间戳和进程 PID,方便比对崩溃前后行为Restart=always 类配置会让 systemd 隐蔽重启,日志里会出现连续的 Started → Starting → Started 循环,但中间缺失败记录——这时要加 --all 参数才能看到被截断的退出详情服务突然消失且无明确错误日志,大概率是被内核 OOM killer 终止。这类重启不会走正常退出流程,systemd 日志里只写 Killed,不带退出码。
dmesg -T | grep -i "killed process",若输出类似 [Tue Apr 2 10:23:45 2025] Killed process 12345 (myserver) total-vm:2.1g, anon-rss:1.8g,基本坐实systemctl show | grep MemoryLimit 查服务是否设置了内存限制;没设的话,OOM 判定依据是整个系统的可用内存,而非服务独占资源MemoryMax 和 v1 的 MemoryLimit 行为不同,v2 中超限会直接触发 OOM,v1 可能只 throttle
看似独立的服务,常因上游依赖(如数据库、Redis、etcd)连接失败而反复退出,systemd 默认重试策略会掩盖真实原因。
systemctl cat ,确认是否有 After=、Wants=,但缺失 Requires= 或 BindsTo= —— 前者只控制启动顺序,后者才做强依赖校验ExecStartPre=/usr/bin/sh -c 'until nc -z dbhost 5432; do sleep 2; done',避免盲目启动systemctl list-dependencies --reverse 能暴露循环依赖频繁重启未必是代码问题,可能是 systemd 自身的节流机制在“假装稳定”。比如服务 5 秒内崩溃 3 次,后续所有启动请求都会被直接拒绝,直到窗口期结束。
systemctl show | grep -E "(StartLimit|RestartSec)" ,重点关注 StartLimitIntervalSec= 和 StartLimitBurst=
StartLimitIntervalSec=10 + StartLimitBurst=5,意味着 10 秒内最多允许 5 次启动尝试,超限后 systemctl start 会立刻返回 Failed to start unit: Unit is disabled(实际是被限流,不是 disabled)StartLimitIntervalSec=0(禁用限制),但上线前必须恢复,否则掩盖真实故障真正难定位的不是崩溃本身,而是那些不报错、不打日志、甚至不触发 OOM 的重启——比如挂载了 bad NFS 共享导致进程卡在 D 状态,或 seccomp 规则拦截了关键系统调用后静默退出。这时候得切到 strace -p 或 bpftrace 抓现场 syscall,不能只盯 journalctl。