为什么我的服务器总在半夜重启?常见原因排查

为什么我的服务器总在半夜重启?常见原因排查

你早上醒来打开监控,发现服务器在凌晨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看看上次启动的内核日志,那里面通常已经写好了答案。

知识库

Nginx日志格式定制:如何记录更有价值的访问信息?

2026-7-27 16:31:51

实操指南知识库

Serverless 架构在云计算中的应用与实践

2024-12-20 12:22:09