
你早上醒来打开监控,发现服务器在凌晨3点重启过一次。没人在线,没有操作,日志里也没有明显的报错。它自己重启了,然后自己回来了,留你一个人困惑。
半夜重启的问题比白天更难查,因为你不在现场,而且大多数排查手段需要在重启前完成。但如果你知道去哪里看、看什么,答案通常就藏在系统日志里。
第一步:确认什么时候重启的
排查从建立时间线开始。先弄清楚上一次启动是什么时候,以及历史上发生过多少次重启。
bash
# 查看当前系统启动时间
who -b
# 列出所有重启记录(带时间戳)
last reboot | head -20
# 查看最近的重启/关机事件
last -x | grep -C1 'shutdown\|reboot' | head -30
last reboot会显示每次重启的时间戳,帮你快速判断这是偶发事件还是规律性重启。如果看到每周固定某天重启,大概率是系统更新或计划任务触发的。
第二步:查看上一次启动的日志(最关键)
重启后,当前启动日志覆盖了重启之后的信息,上次启动的日志才是你要查的。在systemd系统上,用-b -1查看上一次启动的日志:
bash
# 查看上次启动的最后200行日志 journalctl -b -1 --no-pager | tail -200 # 查看上次启动的内核日志 journalctl -b -1 -k --no-pager | tail -100 # 搜索上次启动中的panic/oom/error关键信息 journalctl -b -1 -k --no-pager | grep -iE 'panic|error|critical|fatal|kernel bug|general protection'
重点搜索的关键词:Kernel panic(致命内核错误)、Out of memory(内存耗尽)、soft lockup(CPU被长时间占用)、watchdog(看门狗超时)、ACPI(电源/温度事件)。
第三步:分析常见重启原因
原因一:OOM Killer 杀死了关键进程
当系统物理内存和交换分区全部耗尽时,内核会调用OOM Killer强制终止进程以维持系统运行。如果被终止的是systemd或MySQL这类关键服务,可能引发连锁反应导致系统重启。
bash
# 检查OOM事件 journalctl -b -1 -k --no-pager | grep -i 'out of memory\|oom\|killed process'
如果看到类似Out of memory: Killed process PID (name) total-vm:xxx的记录,说明内存不足是元凶。
原因二:Kernel Panic(内核崩溃)
内核遇到无法恢复的致命错误时,会触发panic。常见诱因包括驱动bug、硬件通信故障、内存错误等。
bash
journalctl -b -1 -k --no-pager | grep -iE 'kernel panic|oops|bug:'
检查系统是否配置了panic后自动重启:
bash
cat /proc/sys/kernel/panic # 返回0:panic后挂起,需人工干预;返回N:panic后N秒自动重启
原因三:CPU锁死(Soft/Hard Lockup)
某个进程长时间占用CPU不放,或者CPU完全不响应中断时,内核看门狗会触发重启。
bash
journalctl -b -1 -k --no-pager | grep -iE 'soft lockup|hard lockup|nmi watchdog'
原因四:人为操作或计划任务
半夜重启也可能是cron定时任务或运维脚本触发的。
bash
# 检查当前用户的定时任务 crontab -l # 检查系统级定时任务 cat /etc/crontab ls /etc/cron.d/
第四步:区分软重启和硬重启
判断重启类型可以帮助缩小排查范围。如果日志中有完整的关机流程(如exiting on signal 15),是正常的软重启。如果日志缺失,像是直接断电,说明可能是硬重启。
| 特征 | 软重启 | 硬重启 |
|---|---|---|
| shutdown记录 | 有关机服务停止日志 | 无正常关机流程 |
| dmesg时间戳 | 连续或平滑结束 | 可能出现时间断层 |
| 文件系统检查 | 正常sync | 异常后启动时可能触发文件系统检查 |
一个真实案例
某服务器每2-3天半夜自动重启一次。检查journalctl -b -1 -k发现每次重启前都有Kernel panic - not syncing: Fatal exception in interrupt记录。进一步查看cat /proc/sys/kernel/panic返回10,意味着panic后10秒自动重启。排查发现网卡驱动在特定流量模式下触发bug导致panic,更新驱动后问题解决。
预防与监控
如果做了以上排查还是找不到明确原因,可以配置kdump捕获内核崩溃现场。kdump会在kernel panic时保留内存镜像,供后续分析:
bash
# 安装kdump工具 yum install -y kexec-tools # 在/etc/default/grub中添加crashkernel参数 # GRUB_CMDLINE_LINUX="... crashkernel=256M" # 重新生成grub配置 grub2-mkconfig -o /boot/grub2/grub.cfg # 启动kdump服务 systemctl enable kdump systemctl start kdump
最后一句
半夜重启通常有三类原因:内存不足(OOM Killer)、内核panic、硬件触发。但如果你不知道去哪里看日志,这三类原因看起来都一样——系统日志里找到具体的关键词,才能把问题定位到具体方向。下次服务器半夜重启了,先别急着重启服务。用journalctl -b -1 -k看看上次启动的内核日志,那里面通常已经写好了答案。




