
半夜两点手机疯狂报警机房值班电话打过来的时候我就知道服务器又出事了。跑过去一看系统已经自动重启完毕所有服务刚刚拉起来日志里只有一段莫名的启动记录之前发生了什么完全不知道。这种查无实据的自动重启排查应该是每个搞Linux运维的人都经历过的噩梦。所谓查询Linux自动重新启动原因本质上就是一次事故复盘系统不会无缘无故重启每一次重启背后都有迹可循关键是你知道去哪里找、怎么找、找到之后怎么看。这篇文章我会按照真实的排查链路来写从最基础的日志时间线还原到内核崩溃抓取、硬件状态研判、软件配置挖坑再到完整的实战案例拆解。内容适合刚接手服务器运维的新人也适合被这个问题困扰已久、想找个系统性排查思路的老手。1. 自动重启问题先分清是死给你看还是悄悄重启排查第一天你就得明白一个道理自动重启不是一个单一故障而是一类现象的总称。不同重启类型对应的取证方向完全不同方向和对象搞错了后面全白费。1.1 两种截然不同的重启模式先看系统的最后一次关机和启动记录。重启大体分两类内核崩溃后的强制重启panic重启这时候内核检测到无法恢复的致命错误。系统是否自动重启取决于内核启动参数里有没有配置 panic 后的行为。如果在/proc/sys/kernel/panic里看到的数值是大于0的秒数那表示 panic 后多少秒内自动重启。这类故障通常是硬件损坏、内核bug、关键驱动异常引起的证据往往在内核崩溃日志里。非panic的正常重启clean reboot系统按照标准流程关闭服务、卸载文件系统、写入日志后才重启。这种重启的反常之处在于——没人按过重启按钮它不是人为操作的结果所以你得往系统服务、定时任务、看门狗、电源管理、远程管理卡这些方向去找。判断方式很直接。如果上次关机前日志里有完整的Stopped/Deactivated记录然后系统干净利落地关机那属于第二类如果日志突然中断没有任何收尾过程下一段记录就是引导信息那多半是第一类。1.2 物理机、虚拟机、云主机排查方向完全不同同一台出了自动重启问题的机器放在不同环境里嫌疑对象的优先级天差地别环境类型优先排查方向原因物理机自建机房硬件故障、温度、电源、内存、远程管理卡误触发所有硬件都裸奔任何一层出问题都会直接反映到系统物理机托管/租用机房断电、IPMI/BMC侧重启、机房人为误操作你的系统层面看到的信息可能只是冰山一角虚拟机KVM/VMware宿主机负载过高、内存超分、宿主机自身维护、迁移虚拟机感知到的断电重启很可能来自宿主机云主机云厂商宿主机维护、热迁移失败、安全策略你有相当一部分控制力被云平台抽象掉了日志可能被截断我自己踩过的一个坑帮客户排查一台物理机无故重启查了两天最后发现是机房那边的BMC管理口被人误触发了一次重启指令。系统日志里干干净净没有任何异常因为那个级别的重启根本不会经过操作系统。所以接到自动重启的工单第一件事不是翻日志而是先搞清楚这台机器在什么环境里并且向相关人员机房、云平台客服、同事确认有没有人手操作过。有时候答案就在工单系统里你只是还没问。2. 第一站必查journalctl与系统日志的时间线还原不管前面怎么分类日志永远是第一手证据。systemd 时代journald 基本接管了所有日志收集加上传统的/var/log/messages和/var/log/kern.log足够还原出机器重启前后的完整时间线。2.1 journalctl --list-boots先看启动记录总表这条命令是我的固定起手式journalctl --list-boots输出会列出每次启动的序号、启动时间、结束时间以及对应的日志ID。注意-1表示上一次启动-2是上上次以此类推。通过这张表你能快速看出这台机器最近的重启频率。如果每天固定时间重启大概率跟定时任务有关如果是毫无规律地隔三差五重启硬件嫌疑更大。拿到启动序号之后重点看上一次启动-b -1的日志尾部。系统重启前最后几行往往藏着真正的死因journalctl -b -1 -e # 查看上一次启动的最后20行 journalctl -b -1 -p err # 只看上一次启动的错误级别日志如果-b -1里最后记录的还是一些正常的服务运行信息随后戛然而止这就指向硬件类故障或内核panic。如果日志里有大量的Out of memory、hung_task_timeout_secs、blocked for more than 120 seconds这类记录那就是资源层面的问题导致系统假死随后被看门狗或人为策略给重启了。2.2 传统日志文件同样不能跳过journald 的缺点是日志默认不持久化。如果你碰到一台已经运行了很久的机器重启后只能看到重启当下开始的日志之前的历史全在内存里蒸发掉了那就只能求助传统日志文件tail -n 200 /var/log/messages tail -n 200 /var/log/kern.log tail -n 200 /var/log/syslog/var/log/messages是通用系统消息很多服务的启动停止痕迹都在里面/var/log/kern.log单独记录内核日志panic之前的内核警告、硬件报错、文件系统错误都会在这里。很多发行版还有/var/log/dmesg的持久化记录但需要确认有没有开启rsyslog的对应规则。不建议只抓一个文件看。我一般会把三个文件里重启前半小时的记录全部拉出来放到一个文件里按时间排序然后人工过一遍。很多时候问题不会直接写我重启了而是一连串看似无关的报错组合起来最终导致系统走到重启那一步。2.3 时间线还原用last和uptime交叉验证日志只是过程重启这个结果本身的记录也有专门的查看方式last reboot # 查看历史重启记录 last -x shutdown # 查看带原因的关机记录 who -b # 查看最近一次系统启动时间 uptime -s # 系统启动的时间点last -x shutdown的结果值得仔细看。如果显示的系统关机时间和你预期重启时间对不上说明这台机器可能在你的时间线之外还发生过一次掉电或硬重启。配合journalctl --list-boots和last reboot的输出就能构建出这样一条时间线22:13:05 系统正常关机日志有Stopped记录22:13:40 系统开始引导停机期间约35秒如果系统日志显示的是正常关机但你明确知道没有人执行过关机命令那问题就指向shutdown/reboot命令被某个进程调用了。这时候反向搜索调用来源用journalctl -b -1 | grep -i shutdown\|reboot\|poweroff找线索往往能挖出定时任务或脚本。3. 内核崩溃与硬件故障kdump、mcelog与温度引发的血案到了这个环节你已经确认了重启属于非正常断电/恐慌重启的类型。接下来要把硬件层面和内核层面的可能性一个个排掉。3.1 内核panic后的证据kdump与crashkernel如果机器配置了内核崩溃转储kdump内核panic时会把内存镜像保存下来之后系统重启。这个镜像文件通常是排查内核崩溃最硬的证据。检查kdump是否配置cat /proc/cmdline # 看有没有 crashkernel 参数 systemctl status kdump ls /var/crash/ # 崩溃转储文件存放位置我在生产环境里见过很多重装系统后忘记配置kdump的案例导致系统panic后只会重启什么证据都没留下。如果你确认机器有明显的panic重启嫌疑但 /var/crash 是空的先查/proc/cmdline里有没有crashkernelauto或类似参数。没有的话这就是个小隐患平时无所谓出问题的时候欲哭无泪。kdump保存下来的vmcore文件可以用crash工具分析对新手来说门槛偏高需要了解内核数据结构。更接地气的做法是看panic那一刻内核在做什么。不过大多数情况即使没有kdump内核在panic前也会在/var/log/kern.log里留下大量线索包括但不限于Kernel panic - not syncingOops或BUG: unable to handle kernel paging requestRIP:后的函数名和偏移量Call Trace:调用栈只要看到这些关键字的任意一条内核层面的嫌疑就锁定了。配合dmesg -T查看panic之前的硬件态基本能确定方向。3.2 mcelog与EDAC内存错误是最大的隐形杀手内存条上的单个bit翻转是Linux系统随机崩溃的头号元凶。它有多隐蔽呢可能系统已经Ecc纠错了好几次你毫无感知也可能纠错越界直接触发panic。但有一个前提——你得装mcelog或者rasdaemon去记录这些硬件错误。# 查看当前是否有硬件错误记录 mcelog --client ras-mc-ctl --summary dmesg -T | grep -i edac\|mce\|memory error如果日志里出现EDAC MC0: CECorrected Error可纠正错误或者Uncorrected Error的记录内存条已经在向你报告它撑不住了。CE错误多而频繁时通常意味着内存条处于劣化状态建议尽快更换。我遇到过一台机器平均每三天凌晨4点重启一次白天怎么压测都不出问题最后是日志里密密麻麻的内存CE错误暴露了问题——凌晨温度低硬件对时序更敏感错误率升高最终触发panic。3.3 温度、电源和SMART硬件说话的三板斧温度过高导致自动重启在物理机上非常常见尤其是刀片服务器和密布机柜的环境apt install lm-sensors # Debian/Ubuntu系 yum install lm_sensors # CentOS系 sensors # 查看传感器读数看CPU、主板、硬盘各传感器温度。如果CPU温度在平时就徘徊在85°C以上那不是重启的原因也快了。散热器积灰、风扇转速不足、机房空调故障这类运维琐事往往能引发大事故。电源模块的判断比较难因为多数服务器电源故障不会先给系统报错而是直接掉电、然后瞬间上电重启。日志的表现就是断了就再起前面没有任何错误记录。如果日志表明系统非常突兀地没有收尾就直接从引导开始的电源PSU和主板供电都值得怀疑。最后是硬盘smartctl -a /dev/sda # 查看硬盘健康信息重点关注Reallocated_Sector_Ct、Pending_Sector、UDMA_CRC_Error_Count这几项。虽然硬盘故障更多造成的是文件系统错误而不一定是整机重启但某些平台的磁盘控制器异常也会触发系统panic。4. 软件层暗坑定时任务、服务守护与内存不足(OOM)引发连锁重启硬件查完没发现问题或者日志里压根没有硬件报错就得把目光转向软件侧。以下四类软件层面的原因是我处理过的自动重启工单里命中率最高的。4.1 OOM killer与内存耗尽系统被饿死后重启Linux有一个臭名昭著的机制当内存耗尽时内核的OOM killer会挑选一个进程杀掉。但更严重的情况是——内存耗尽到连OOM killer自身都无法正常工作或者触发了hung_task检测系统就会进入濒死状态。如果内核配置了panic_on_oom1或者系统的watchdog检测到关键进程卡死就会触发自动重启。journalctl -b -1 | grep -i out of memory\|oom dmesg -T | grep -i oom\|hung_task cat /proc/sys/vm/panic_on_oom我见过一个典型案例业务团队部署了一个内存泄漏的Java进程跑了七天把内存吃光然后系统OOM切到重启。日志里可以看到OOM killer反复尝试kill进程但新进程马上又占满内存最终触发重启。解决方向很简单限制进程内存、修泄漏、加物理内存以及调优swappiness。4.2 定时任务里藏着一个reboot排查自动重启时检查root用户的crontab和/etc/cron.d/一定要排在最前面。原因很简单这条路径最短、最容易被发现但总有人会漏掉。有人可能觉得谁会往crontab里写reboot呢事实是很多自动更新脚本里冗余的reboot、某些安装向导留下的reboot任务、甚至前同事测试时写的定时重启计划都可能成为幽灵重启的来源。crontab -l -u root cat /etc/crontab ls /etc/cron.d/ grep -r reboot\|shutdown /etc/cron* /var/spool/cron 2/dev/null另外别忘了/etc/cron.daily、weekly、monthly目录下的系统维护脚本有些发行版或第三方程序会在这些脚本里嵌入重启逻辑。4.3 systemd服务的Restart与Watchdog设定systemd下服务配置里Restart配合RestartSec可以在服务异常退出时自动拉起这本身不会导致整个系统重启。但如果你看到的是服务挂了之后系统随之重启那要看另一个东西systemd的RuntimeWatchdogSec硬件看门狗。它会在系统响应超时后重启机器。systemctl show | grep -i watchguard cat /etc/systemd/system.conf | grep -i RuntimeWatchdogSec\|RebootWatchdogSec还有些特殊服务比如panic-on-oops触发的内核oops会被当作panic处理进而走内核自动重启的路径。这类问题一般会伴随内核日志里的Oops字样。4.4 无人值守更新和内核崩溃参数Ubuntu/Debian系环境的unattended-upgrades定时更新很多版本更新完不会自动重启但某些内核安全更新或配置策略可能会触发重启。之前热搜词里提到ubuntu22.04会自动重启很大程度上就是这个原因——新版Ubuntu的needrestart机制会在内核更新后提示或自动重启服务如果配置了自动重启的交互策略就会给人留下系统没事自己重启的错觉。另外检查内核启动参数里关于panic的配置非常关键。/etc/sysctl.conf和grub的GRUB_CMDLINE_LINUX中kernel.panic的值决定了panic后的行为。如果kernel.panic 0系统panic后会卡住不动不会自动重启等你看到的现象是出问题后自动重启反而说明这个值是刻意配过的sysctl kernel.panic cat /proc/sys/kernel/panic实际上我配生产环境服务器时会有意识地设置kernel.panic 10让系统在panic后自动重启以快速恢复服务。但这带来一个副作用自动重启掩盖了真正的原因。如果没人盯着崩溃现场后续排查会非常痛苦。所以才必须配合kdump和远程日志。这是一个典型的可用性和可观测性打架的运维难题。5. 两个真实排查案例从日志到结论的完整链路写前面几个部分时总感觉缺了点现场感这节干脆复盘两个完整的排查案例。一个来自虚拟机环境一个来自物理机环境链路足够有代表性。5.1 虚拟机的凌晨三点半重启最终抓到定时任务客户的虚拟机是KVM平台Ubuntu 20.04运行着一个Nginx和几个Java服务。现象是每天早上3:30左右自动重启一次客户非常笃定地说绝对没有安排过重启计划。第一步我还是走了journalctl --list-boots确认过去7天每次重启都在凌晨3:28~3:32之间这个规律性强烈暗示定时任务。但查看/var/spool/cron和/etc/cron.d都没有发现异常。于是我把检查范围扩大到/etc/crontab支持的所有目录以及systemd timersystemctl list-timers --all find /etc/systemd/system -name *.timer -exec cat {} \;真凶藏在/etc/cron.d/下一个不起眼的logrotate相关脚本里——某个程序升级时在脚本末尾残留了一行systemctl reboot。正常情况下不会触发但因为脚本里前一个步骤失败了错误处理逻辑反而走到了最后的重启分支。这个案例想说明排查定时触发的问题规律性是最强线索。一旦确认时间规律基本可以在脚本和任务层面穷举搜索。同时不要只盯着crontabsystemd timer、anacron、at任务都应该纳入检查范围。5.2 物理机随机重启内存CE错误被忍了很久另一台物理机每周大概随机重启两三次完全无规律。业务影响不大但每次重启都要人工确认报警、恢复服务客户被折磨得不行。日志层面重启前没有任何shutdown过程直接就是引导信息——这是硬重启的典型特征。dmesg -T里没有任何panic痕迹但能看到零星的EDAC报错EDAC MC0: 1 CE on DIMM3 EDC MC0: 1 CE on DIMM3虽然报错频率不高但DIMM3这个槽位反复出现已经不是随机干扰的范畴了。进一步用mcelog --client查到更早的历史错误记录发现DIMM3上的可纠正错误在过去一个月里累计了几十次集中在最近一周。后续处理就是停机、替换DIMM3内存条、加压测试三天重启问题彻底消失。这个案例是我们排查自动重启问题的经典思路即使硬件报错频率不高也不能忽略。很多CE可纠正错误被当作无所谓但它们往往是UE不可纠正错误的前奏后者才是直接引发系统panic和重启的元凶。6. 排查工具箱与预防手段让下一次幽灵重启无处遁形排查完一个问题不等于万事大吉。真正有经验的运维一定会趁热打铁把手上的战果变成常态化的防御能力。下面是的固定套路。6.1 建立重启排查命令速查表每次接到自动重启工单按以下顺序走一遍效率最高# 1. 重启总览 last reboot journalctl --list-boots uptime -s # 2. 定位异常时刻 journalctl -b -1 -p err -e # 3. 分析关机类型干净/异常 journalctl -b -1 | grep -i shutdown\|reboot\|poweroff # 4. 检查硬件记录 dmesg -T | grep -i error\|fail\|edac\|mce\|temperature mcelog --client 2/dev/null || ras-mc-ctl --summary 2/dev/null smartctl -a /dev/sda 2/dev/null | grep -i reallocated\|pending\|error # 5. 检查软件触发源 crontab -l -u root ls /etc/cron.d/ grep -r reboot\|shutdown /etc/cron* /var/spool/cron systemctl list-timers --all sysctl kernel.panic cat /proc/cmdline这套流程不需要一次全部执行但要保证自己心里有数哪一步针对哪类原因没有结果就跳到下一步。6.2 持久化日志别再让重启抹掉案发现场journald默认把日志写在内存中重启即失这对排查自动重启来说是致命的。所以第一步防御就是开启journald持久化mkdir -p /var/log/journal systemd-tmpfiles --create --prefix /var/log/journal systemctl restart systemd-journald另外强烈建议配置远程日志服务器。把kern.*和*.error级别的日志实时转发出去。方法不复杂——本地装rsyslog配置*.* 192.168.1.100:514远程日志服务器不用太好能收就行。一旦本地日志被重启折腾丢了远程日志就是最后一道防线。6.3 关键配置建议与常见的BIOS项最后给几点预防性配置建议开启kdump给内核预留 crashkernel 内存段配好/var/crash目录这样即使内核panic宕机虚拟机也能留下完整的断言现场。内核panic策略生产环境建议kernel.panic 10配合kdump做到崩了能重启重启有证据。如果不是这类高可用诉求保持默认0即可至少不会掩盖问题。配置硬件监控安装lm-sensors和smartmontools通过脚本定期采集温度与磁盘健康状态到监控系统。管理BIOS里的Watchdog很多服务器BIOS默认开了TPM或IPMI的看门狗超时功能一旦固件层面某个操作挂起BMC会直接帮你重启机器。这种重启操作系统完全无感知日志里干净得可怕。新机器到手务必进BIOS确认看门狗策略和电源策略比如断电恢复后是否自动开机。每次排查完自动重启问题我都会把完整的排查过程、关键日志摘录、最终根因写成一页简短的报告放进团队的运维知识库里。几个月后你会发现很多问题的模式是重复的抄起之前的报告能少走很多弯路。另外说个比较反直觉的经验越想把系统配置得稳定越要主动增加它的可观测性。你宁可多花半小时把kdump、日志转发、硬件监控全部配好也不要祈祷这台机器永远不会再重启。生产环境里机器不宕是不现实的但宕了之后你拿不拿得出证据才是一线运维和“据说运维”的分水岭。