干运维这些年最常被问的一个问题是同样是看告警、排故障为什么有人半小时定位问题有人折腾一宿还找不着北我一直觉得差别不在经验多少而在脑子里有没有一套清晰的运维故障排查思路。今天想聊的就是这套思路里最核心的两条原则先定位后解决先硬件后软件。这两句话看着朴素但实操中绝大多数翻车现场根子上都是把顺序搞反了。要么上来就猜“是不是配置改坏了”然后一头扎进配置里翻半天要么不管三七二十一先把服务重启一遍看着恢复了就收工结果第二天凌晨又被同样的告警叫醒。故障排查不是玄学它是有方法论、有优先级、有固定动作的。把这个顺序捋顺了你会发现很多告警根本不需要“救火式”处理几分钟就能锁定根因。这篇内容是写给谁的呢主要是运维工程师、SRE、后端开发里需要自己顶上排查问题的人也适合刚入行、面对告警不知道从哪下手的萌新。同时如果你只是在家修自己的电脑、服务器这套思路同样管用。因为“先定位后解决先硬件后软件”本质上是一套通用的排查框架设备可以换系统可以换框架不用换。1. 先搞清楚一件事绝大多数排查失误都坏在“想当然”1.1 为什么“先定位后解决”能救命先说个场景。某天线上报了一个告警某个服务接口超时率飙升。新手的第一反应往往是赶紧打开服务端日志看看是不是代码抛异常了。运气好日志里确实有报错于是顺着报错往上追折腾两小时后发现——报错来自下游数据库数据库本身因为磁盘满了正在只读。这就是典型的定位缺失。如果先做定位你要回答的是几个更基础的问题这个故障影响了谁是所有请求都超时还是只有一部分是从哪个时间点开始的在故障发生前后有没有发布、变更、扩容有没有规律性比如每小时的某个整点就抖一下这些问题不需要任何深入分析只需要看监控、翻告警、问同事往往几分钟就有答案。但它们能直接决定你下一步该往哪个方向走。我见过太多排查事故问题其实不大但处理的人没有先定位上来就“基于经验”动手觉得是缓存穿透就把缓存调大觉得是GC太频繁就改了一堆JVM参数。一顿操作猛如虎之后发现现象还在。等到实在没辙了才去看监控大盘才发现是上游某个流量入口的负载均衡器在重启。绕了一大圈原理很简单没有定位就直接解决本质上是拿猜测代替证据。定位的意义在于把“一个模糊的故障陈述”翻译成“一组明确的问题边界”。只有边界清晰了解决方案才能精准。否则你所有的排查动作都是在“打地鼠”按下一个起来一个。1.2 “先硬件后软件”的顺序不是教条而是性价比最高的一条路“先硬件后软件”这条原则很多新手理解成了“把所有硬件都检查一遍再碰软件”。这不是本意至少不是字面上的顺序。它的核心意思是在排查过程中优先排除掉那些位于底层、一旦出问题会让所有上层现象都变得“不可信”的变量。打个比方。你家里灯不亮了你大概率不会先拆开开关研究电路设计也不会上来就怀疑灯泡品牌有问题。你会先看是不是跳闸了再看灯泡是不是烧了最后才考虑开关和线路。为什么因为越底层的变量越容易出问题也越容易被上层故障的表象掩盖。硬件就是这么个存在。内存坏了业务进程会段错误看起来像代码bug网卡丢了服务端口全连不上看起来像防火墙策略错了磁盘IO抖动数据库查询慢得像蜗牛看起来像慢SQL变多。你说如果不先把硬件嫌疑排除你在软件层分析半天分析得再漂亮不还是被表象带着跑吗更重要的是现在服务器的硬件层排查成本极低。带外管理、事件日志、SMART信息一条命令就能拉出来。花两分钟确认硬件没有异常再进入软件排查总比在软件层瞎转两小时、最后发现是内存故障香得多。这不是死板的流程而是基于成本收益比做出的最优选择。2. 先定位后解决把故障钉死在最小范围内2.1 定位的四个维度时间、范围、变更、复现条件我把定位这件事拆成四个维度做排查时按顺序过一遍基本能锚定问题。这四件事与具体技术栈无关什么系统都适用。第一个维度是时间。故障是什么时候开始出现的是持续性的还是间歇性的如果是间歇性有没有固定周期时间维度最大的价值是让你能把故障和某些动作关联起来。比如故障发生在凌晨两点而两点刚好有定时任务在跑那就是很高的嫌疑线索。再比如故障从某次重启之后开始那新内核、驱动加载顺序、服务自启项都是重点方向。第二个维度是范围。到底哪些用户、哪些接口、哪些节点受到了影响是所有地域的请求都失败还是只有某个机房是所有实例都异常还是单台范围能帮你快速判断故障的“传播路径”。比如全部实例同时异常多半是依赖的下游公共组件出问题了单台实例异常那就要重点看这台机器的系统状态。第三个维度是变更。故障时间点前后有没有做过发布、配置修改、扩容缩容、硬件变更我见过不少排查两小时没结论的案例最后发现是最早的时候网络设备升级回切没回干净。变更对故障排查而言是最有指向性的信号。很多公司把“先检查变更”定为铁律不是没有道理的。第四个维度是复现条件。这个问题能不能稳定复现复现需要什么操作如果能稳定复现那排查难度会直线下降——你可以在测试环境操作一次对比一下正常和异常的过程差异点往往就是问题所在。如果不能复现那就需要靠监控、日志和现场信息来做推断难度会大得多但也更能体现定位功夫。这四个维度过完你手里应该有一张相对完整的“故障画像”了。后续不管你查硬件还是查软件都是在这张画像的指引下进行而不是大海捞针。2.2 收集证据的三个层次现象、日志、指标定位不是拍脑袋它靠的是证据。证据也是有层级的从低到高分别是现象、日志、指标。现象是最原始的证据比如“页面打不开”“接口报超时”“机器响蜂鸣器”。现象是所有人第一眼看到的但它也是最容易误导人的。超时可能是网络延迟可能是线程池耗尽也可能是GC停顿现象背后对应的原因太多了。所以现象只能作为出发点不能作为结论依据。日志是系统的“留痕”。应用日志、系统日志、硬件日志每一类日志都在讲述不同层面发生的事这就是我说“运维故障排查思路”里最基础的一环——让系统替你把故事讲完整。查日志有两条经验第一先看时间戳对齐把所有相关日志按时序排列你会发现很多看似无关的记录其实是因果链第二别只盯着ERROR级别WARNING、INFO、DEBUG里的上下文信息往往更重要因为报错只能告诉你“哪里坏了”上下文才能告诉你“为什么坏”。指标是量化证据来自监控系统。CPU、内存、磁盘IO、网络流量、GC耗时、线程数、连接池用量这些指标能客观反映系统的负载状态和变化趋势。当你说“系统很卡”的时候如果CPU只有5%那你所谓的“卡”就值得重新定义了——到底是哪一层卡指标的作用是把模糊的主观感受变成可比对的数据。我的习惯是现象记录到手日志按时间线拉出来指标对着时间线回放。三者能对上定位就完成了一大半。2.3 用排除法缩小边界而不是直接猜原因定位到一定阶段后剩下的问题往往就是二选一A组件有问题还是B组件有问题。这时候最忌讳的是在两个方向之间反复横跳一会儿查A一会儿查B。应该做的是设计一套“可证伪”的测试每次只排除一个变量快速逼近根因。比如一套前后端分离的系统接口报错。是前端的问题还是后端的问题最简单的做法就是直接请求后端接口绕过前端。如果后端接口正常那问题大概率落在前端代码或前后端交互上如果后端接口也报同样的错那问题就锁定在后端范围内了。这就是一个很典型的分流测试。再比如翻数据库慢日志发现一条SQL很慢。是不是这条SQL的问题先把它单独拿出来跑一遍加上索引再跑一遍对比执行计划。如果加了索引就快了说明优化SQL是对的如果加了索引依然慢那可能是表数据量膨胀、硬件IO能力不足或者数据库配置有问题。一次实验只验证一个变量才能得到可信的结论。这种排除法的好处是你的每一步行动都有明确的逻辑支撑排查过程是可回溯的。哪怕最后没找到根因别人也能沿着你的排查路径继续往前走而不是从头再来。3. 先硬件后软件四层检查法按顺序走3.1 第一层供电与物理链路我自己排查故障有个习惯不管问题多“像”软件问题都先花几十秒过一遍“物理层”。因为物理层出问题的概率不低但被忽略的概率极高。先说供电。服务器突然重启、业务进程突然消失、存储设备报写入失败这些场景里供电不稳是很常见的“隐形杀手”。如果是机房托管常见的是PDU电源分配单元插口松动、双路电源只接了一路或者那一路上游跳闸了。如果是自己家里的NAS或工作站那就是插线板老化、电源适配器功率不够。排查时别嫌麻烦看一眼电源指示灯、听一下风扇声音、用万用表量一下供电电压都比在系统里翻日志更快。再说物理链路。网线松了、光纤插头脏了、模块松动都会让网络看起来“时通时断”。特别是那种ping一下通过几秒又不通的现象软件排查再久也没用因为问题不在系统在链路。我习惯先用设备管理口去看网卡状态看link是否反复up/down如果真是这样就直接让人去机房换线、重新插拔光模块。很多人觉得这些都是“最基础的东西”不屑于查。但故障排查恰恰是“先易后难”的活物理层检查成本极低、收益极高查一下不亏。3.2 第二层硬件健康状态物理链路确认没问题之后下一步就是确认硬件本身到底健不健康。这里的数据来源很丰富而且绝大多数不需要重启系统就能拿得到。在服务器场景BMC/IPMI是最重要的信息来源。通过带外管理口你可以直接查硬件事件日志。命令大概是这样的ipmitool sel list ipmitool sel elist ipmitool sensor listsel list里如果出现Memory、ECC、Fault、Critical之类的关键字那这台机器的硬件基本就有嫌疑了。更具体的还有dmesg | grep -i -E edac|mce|memory|hardware|error dmesg -T | grep -i -E error|fail|critical | tail -50dmesg是内核级日志硬件层面的错误往往会在里面留下痕迹。比如内存有不可纠正错误Uncorrected Errordmesg或者mcelog里会记录得很清楚。磁盘健康度则用SMART信息来看smartctl -a /dev/sda重点关注Reallocated_Sector_Ct、Current_Pending_Sector、Offline_Uncorrectable这三项只要有一项数值异常偏高这块盘就不能再继续承担生产负载了。还有很多商用服务器自带检测工具比如戴尔的racadm、惠普的ssacli、联想的storcli都可以查阵列卡和物理盘状态。3.3 第三层固件与驱动硬件本身没坏不代表硬件就“没问题”。固件版本或者驱动不兼容同样会制造出一堆看似无解的故障。这一层最经典的现象就是系统负载很低但IO性能上不去网卡无故丢包GPU计算任务间歇性失败。排查这一层需要做两件事。第一件事是核对固件版本和已知问题清单。比如某款网卡固件在特定内核版本的驱动下会发生死锁某款SSD固件在持续高负载下会掉盘这些信息厂商通常会在发布说明里写明。你只要把当前版本拿出来一对照就能判断是不是踩了已知的坑。第二件事是看看驱动日志里有没有异常。ethtool -i eth0 dmesg | grep -i -E driver|firmware|ixgbe|mlx|link第三层往往是最容易被忽略的一层。因为它既不像纯硬件故障那么明显也不像纯软件问题那么“可控”。但正因如此一旦遇到排查起来特别耗时。如果硬件和软件都查完了还没结论记得回来看看固件和驱动版本说不定真相就在那里。3.4 第四层操作系统与业务软件过完了前面三层才轮到大多数人第一反应就想查的“软件层”。这一层面的排查方法大家都很熟无非是看系统资源、看进程状态、看日志、看配置。真正想提醒的是两件事。第一件事别在软件层浪费太多时间一定要确认“软件层的异常是根因还是结果”。比如服务进程挂掉了这确实是个软件事件但如果你只看进程为什么挂很可能会忽略真正的原因——内存坏了、磁盘满了、系统被OOM Killer干掉。很多人排查故障止步于“服务挂了重启完事”从没问过一句“它为什么挂”。这就是典型的把“结果”当“根因”。第二件事软件层的日志要按“排查思路”去读而不是漫无目的地翻。如果是业务服务异常先看应用日志再看系统级日志journalctl或/var/log/messages然后对照监控指标和硬件日志。如果业务日志里报的是连接失败而系统日志里网卡状态一直正常那就要往网络策略或者对端服务上去查了。这四层检查法本质上是一个“从底层往上层走”的过程。底层先排除上层问题才会浮现出来。用一张表总结一下层级检查内容常用工具/命令典型异常信号物理层供电、网线、光纤、接口万用表、设备指示灯、ethool网卡link反复up/down、设备突然断电硬件层CPU、内存、磁盘、阵列卡ipmitool、dmesg、smartctl内存ECC事件、磁盘SMART异常、传感器告警固件/驱动层固件版本、驱动兼容性ethtool -i、厂商发布说明驱动死锁、IO性能不达标、异常丢包系统/软件层服务状态、日志、配置、代码journalctl、应用日志、监控系统进程崩溃、端口无响应、业务超时4. 实操实录一次数据库服务器“假死”的完整排查光讲方法论有点干我拿一个真实的排障经历来说说这套思路长什么样。整个过程不算复杂但很能说明“先定位后解决先硬件后软件”这两条原则到底是怎么落地执行的。4.1 现象确认与信息收集那天凌晨收到告警一个核心数据库实例的连接数飙升端口探测失败。从监控大盘看实例的CPU、内存、磁盘IO在短时间内都出现了严重飙升随后业务侧开始报大量“无法获取数据库连接”的错误。我按定位四维来过了一遍时间上故障发生前没有发布和变更窗口范围上所有连接这个库的应用都受影响而不只是某一个服务复现条件上是持续故障不是偶发抖动变更上数据库侧和业务侧都没有操作记录。这几个信息综合下来基本可以把“业务代码变更”从嫌疑名单里划掉了重点还是落在数据库实例自身身上。这时候有个坑CPU和内存都飙升网络又连不上很多人会下意识觉得是数据库参数不够、连接池被打满了或者有慢SQL在拖垮实例。但我没有急着去看数据库配置和慢查询日志而是决定先把硬件层排除掉。4.2 硬件层排查我先通过带外管理口连上这台服务器的BMC用IPMI查系统事件日志。命令很简短ipmitool sel list | tail -30日志里出现了好几条内存相关的记录其中有两条是关键事件3 | 03/05/2024 | 02:13:45 | Memory #0x05 | Correctable ECC | Asserted 4 | 03/05/2024 | 02:13:47 | Memory #0x06 | Uncorrectable ECC | Asserted看到Uncorrectable ECC的时候我心里基本有数了。可纠正的ECC错误量多说明内存在持续报错不可纠正的ECC错误出现说明已经有数据无法被硬件纠正系统很容易出现随机性的进程崩溃或内核 panic。这个时间点02:13也正好和业务侧感知到故障的时间对上了。为了进一步确认我又看了系统日志dmesg -T | grep -i -E error|mce|memory | tail -50里面同样出现了Kernel panic - not syncing: Machine Check之类的信息指向硬件级机制触发的系统异常。排查到这里硬件层的证据已经非常充分了嫌疑基本锁定在物理内存条上。4.3 软件层确认让“受害者”说话按照原则硬件证据充分后软件层还是要做一遍“确认性排查”——不是为了翻天覆地而是要确保没有第二个根因叠加在里面。我主要看了系统日志里进程的记录确认是不是数据库进程被系统杀掉还是整个内核直接panic。这两者性质完全不同。从日志看系统在中途发生过内核panic随后自动重启。重启后数据库服务尝试恢复但因为内存错误仍在持续进程反复崩溃导致端口一直无法正常监听。应用侧看到的表现就是“连接失败”和“CPU飙升”——CPU飙升很可能是内存错误导致的反复重试和系统软中断异常。到这里软件层的异常都能被硬件层的根因解释通没有第二个独立问题。4.4 修复与复盘定位到根因之后解决反而是最不费力的一步。联系机房同事现场指出出问题的内存槽位更换内存条重新开机校验ipmitool sel clear ipmitool sensor list | grep -i -E mem|temp硬件报警消除后数据库服务正常拉起业务流量恢复。整个过程里真正耗时间的不是“解决”而是“定位”那一步——确认范围、排除干扰、锁定硬件、验证软件是否无辜。复盘这次故障有两点印象很深。第一如果我当时不查硬件直接按“数据库连接池被打满”去调参数可能折腾到天亮都解决不了问题因为根因根本不在那。第二硬件日志的证据价值极高一条Uncorrectable ECC基本就是破案的关键证据比软件层任何日志都简洁有力。这也再次验证了“先硬件后软件”的含金量。5. 常见问题与排查技巧实录5.1 几个容易误判的典型场景日常答疑里有些“故障”反复出现在不同人身上我干脆整理成一段。第一个典型场景是“重启就好了要不要管”。我的建议是如果不采集证据就重启等于销毁案发现场。至少先把能拿到的日志、监控、硬件状态截图保存一份再重启恢复。恢复业务优先级当然高但留证据同样关乎你后续能不能彻底根治问题。第二个典型场景是“网络通不代表服务通”。常见的情形用ping测试机器IP是通的但业务端口连不上于是怀疑防火墙。实际上ping走的是ICMP和TCP业务端口完全不是一回事。排查时至少要用telnet、nc或者ss去确认端口监听状态和连通性再结合防火墙策略做判断。第三个典型场景是“告警时间不等于故障开始时间”。告警是阈值触发的可能故障已经悄悄酝酿了半小时指标才突破阈值。回看监控曲线时要把时间窗口往前推才能看到故障真正的萌芽点。第四个典型场景是“多故障叠加”。有些时候硬件快挂了会导致性能劣化性能劣化又引发业务超时业务超时又触发重试风暴最后整个系统像多米诺骨牌一样全倒。如果你只盯着最表面的业务超时很容易漏掉底层诱因。所以排查时要把证据链串起来问一句“这个现象是不是另一个现象的原因导致的结果”而不是孤零零地处理单个告警。5.2 常用命令与信息速查表在服务器上排查时我习惯把这些命令直接放在手边。这里分享一份速查表覆盖“刚接到告警时最值得先跑的一批命令”排查对象命令/工具一句话提示硬件事件ipmitool sel list先看带外日志硬件故障一目了然内核/硬件日志dmesg -T | grep -iE error|mce|memory找内存、CPU相关的硬件报错系统负载总览top、htop、uptime看load、CPU、内存整体状态磁盘IOiostat -x 1、iotop确认磁盘是否成为瓶颈存储/磁盘健康smartctl -a /dev/sda、storcli/ssacli查物理盘和阵列卡状态网络连通/监听ss -tlnp、telnet ip port确认服务监听和端口连通性系统日志journalctl -xe、tail -f /var/log/messages看系统级报错特别是OOM、cgroup、网络服务状态systemctl status service、systemctl --failed先看异常服务有哪些关键变更记录ls -lt /etc/、rpm -qa --last、发布平台记录按时间点反查变更这些命令不是跑一遍就完事跑完要学会“交叉对照”。比如top里CPU打满接着看是不是某条SQL、某个进程、某个虚拟机的CPU steal导致的再往下看是不是宿主机邻居在抢资源一层一层追。5.3 最后再分享几个小习惯说完了方法和案例还想聊几个我多年实践下来的习惯。第一个习惯是写排障记录。每次排查完我会把现象、证据、定位过程、根因、解决办法整理成几行字按时间归档。这既是给团队沉淀知识也是在训练自己的排查思维。写记录的过程其实就是逼自己把“猜”变成“逻辑链”的过程。写得多了下次遇到相似告警定位速度会快一大截。第二个习惯是把排查动作和恢复动作分开。优先恢复业务没错但每一步操作都要有个记录至少自己清楚“我动了什么”。尤其是线上环境改配置前必须先备份改完要能回滚。见过太多因为恢复操作太粗暴反而引发二次故障的案例。第三个习惯是保持怀疑尤其是对“已知结论”。当所有人都在说“这个模块一直很稳不可能出问题”的时候你反而要去检查它。很多故障之所以排查很久是因为大家下意识地排除掉了“不可能出问题的组件”但事实恰恰是它出了问题。第四个习惯是定期做“故障演练”。不一定要多复杂哪怕每个月挑一个组件人为制造一个故障走一遍完整排查流程都能让团队的故障响应能力有明显提升。纸上谈兵一百次不如实际断一次网、拔一块盘、杀一个进程。这些习惯都不难难的是在压力下依然坚持做。故障排查这件事本质上拼的不是智商而是纪律。你越是在慌乱的时候守住“先定位后解决先硬件后软件”这条线系统就越不会让你失望。