需结合 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。

systemd 服务状态日志怎么看
服务频繁重启时,systemctl status 只显示最终状态,容易误判为“已启动”,实际可能刚崩溃又拉起。必须结合日志看完整生命周期。
- 用
journalctl -u查最近 100 行,重点找-n 100 --no-pager exited with code、Killed、Segmentation fault等关键词 - 加
-o json-pretty可看清每条日志的时间戳和进程 PID,方便比对崩溃前后行为 - 注意
Restart=always类配置会让 systemd 隐蔽重启,日志里会出现连续的Started→Starting→Started循环,但中间缺失败记录——这时要加--all参数才能看到被截断的退出详情
OOM killer 杀进程怎么确认
服务突然消失且无明确错误日志,大概率是被内核 OOM killer 终止。这类重启不会走正常退出流程,systemd 日志里只写 Killed,不带退出码。
- 运行
dmesg -T | grep -i "killed process",若输出类似[Tue Apr 2 10:23:45 2024] Killed process 12345 (myserver) total-vm:2.1g, anon-rss:1.8g,基本坐实 -
systemctl show查服务是否设置了内存限制;没设的话,OOM 判定依据是整个系统的可用内存,而非服务独占资源| grep MemoryLimit - 注意:cgroup v2 下
MemoryMax和 v1 的MemoryLimit行为不同,v2 中超限会直接触发 OOM,v1 可能只 throttle
依赖服务未就绪导致的连锁重启
看似独立的服务,常因上游依赖(如数据库、Redis、etcd)连接失败而反复退出,systemd 默认重试策略会掩盖真实原因。
- 检查
systemctl cat,确认是否有After=、Wants=,但缺失Requires=或BindsTo=—— 前者只控制启动顺序,后者才做强依赖校验 - 在服务启动脚本或 ExecStart 命令前加健康检查,例如:
ExecStartPre=/usr/bin/sh -c 'until nc -z dbhost 5432; do sleep 2; done',避免盲目启动 - 若依赖服务本身也重启中,可能形成雪崩:A 等 B → B 等 C → C 等 A。此时
systemctl list-dependencies --reverse能暴露循环依赖
RestartSec 和 StartLimitInterval 的隐性影响
频繁重启未必是代码问题,可能是 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。










