ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Windows异常排查实战:从事件日志定位到CPU飙高的完整方法论

Windows异常排查实战:从事件日志定位到CPU飙高的完整方法论 Windows这玩意儿平时用着风平浪静一出异常就是连环爆炸早上到公司共享文件夹打不开下午服务器CPU拉满晚上某个服务悄无声息地挂了第二天一看安全日志全是红叉。我这些年从个人电脑到线上服务器排查过的Windows异常类型少说也有几十种蓝屏、网络冲突、驱动翻车、应用启动即退什么场面都见过。折腾多了之后我最大的感受是异常本身不可怕可怕的是没有一套固定的排查思路东一榔头西一棒子最后把系统翻了个底朝天也没找到根因。这篇就把我日常处理Windows异常与排查的经验完整梳理一遍从分类思路到具体命令从日志定位到工具链全部按实际操作来讲适合运维、开发、以及所有被Windows坑过的普通用户参考。1. 先给Windows异常分类排障才不会踩空1.1 系统级异常先看事件日志还是先看进程很多人一遇到Windows异常就打开任务管理器看CPU其实这是最容易走偏的路。系统级异常的核心特征是“整个操作系统层面出问题”典型表现是蓝屏、无故重启、关机失败、服务崩溃、性能突然劣化。这类异常的正确入口是事件查看器而不是任务管理器。原因很简单系统级异常发生时Windows内核和关键服务通常会先写日志再把异常暴露给用户界面。你直接盯着CPU看看到的只是结果不是原因。比如某台机器每隔几天凌晨莫名重启任务管理器当时根本来不及看但事件查看器里一定留下了Kernel-Power 41未预期断电或重启、Event ID 6008异常关机、Event ID 1001蓝屏记录这几条关键线索。我个人的习惯是按下WinR输入eventvwr.msc回车进入“Windows日志→系统”先按时间筛选异常发生前后十分钟的日志。注意看等级为“错误”和“严重”的条目尤其是Event ID 41、6008、1001、1000应用错误这几类。看完系统日志再看应用程序日志如果应用程序日志里有大量Event ID 1026.NET运行时错误或1000基本上可以确定是某个进程在反复崩溃。1.2 网络级异常协议栈三件套网络级异常在所有Windows排查里占比最高而且最容易误判。局域网共享打不开、IP地址冲突、端口被占、内外网不通、某个客户端报“请使用正确网段”这些问题表面看五花八门本质上都离不开协议栈三件套IP地址、端口、协议服务。我的排查顺序从来是先通后细第一步用ipconfig /all看本机IP、子网掩码、网关、DNS是否正常第二步用ping测网关通了再ping对端IP确认二层三层链路第三步用telnet或Test-NetConnection测目标端口确认四层服务是否在监听。很多人一上来就重装驱动、关防火墙、重启路由器这些动作属于“乱枪打鸟”不如先把协议栈每一层验证一遍。需要特别提醒的是Windows上有一个非常隐蔽的坑——Winsock目录损坏。如果ipconfig看着正常、网关也通但某些程序就是上不了网或者网络连接时有时无可以用netsh winsock reset重置一下Winsock目录然后重启。这个操作修复过很多莫名其妙的网络异常代价为零值得永远排在尝试列表里。1.3 应用与开发环境异常环境变量与依赖是重灾区这类异常通常表现为某个软件双击没反应、命令行启动报错、服务起来就退、Java或.NET程序抛异常。它的特殊性在于Windows系统本身可能完全健康问题只出在应用程序的运行环境。最常见的原因是环境变量配置不对。我遇到过很多人在Windows上装Elasticsearch、Hadoop、Flink这类Java生态软件启动脚本双击闪退终端里报“JAVA_HOME is not set”或者“unable to find java”。这时候不要急着重装JDK先检查JAVA_HOME路径是不是存在、路径指向的是不是JDK而不是JRE、PATH里有没有带上%JAVA_HOME%\bin。Windows环境变量修改后需要重新打开终端才生效这个细节能坑掉一半的新手。依赖问题则是另一大坑典型的是Visual C Redistributable缺失、.NET Framework版本不对、OpenSSL DLL找不到。这类问题在事件查看器的应用日志里会有详细记录按图索骥去装对应运行库即可。1.4 硬件与驱动级异常驱动版本比你想的更关键硬件级异常在Windows上体现得最隐蔽。蓝屏代码里如果有DRIVER_IRQL_NOT_LESS_OR_EQUAL、SYSTEM_THREAD_EXCEPTION_NOT_HANDLED这类关键词八成是驱动问题。还有一类更恶心——不蓝屏但设备时好时坏比如无线网卡频繁断连、USB设备偶尔失联、显卡渲染随机花屏。驱动问题排查有个核心原则先确认驱动版本再考虑更新或回退。拿最近很多人遇到的8852CE无线网卡异常举例这块网卡在Windows 11下有多版驱动存在断流问题日志里频繁出现Event ID 5007WLAN接口已断开和网络连接中断。这种问题光看日志是修不好的必须去设备管理器里看驱动日期和版本找到对应版本回退到已知稳定的版本或者安装最新的官方驱动。不要用Windows自动更新帮你装驱动它很多时候装的是“能用但不是最优”的通用版本。另外如果你遇到的是嵌入式设备通过串口或USB接入Windows后随机复位、系统突然重启且没有蓝屏dump别只盯软件。事件日志如果只有Kernel-Power 41没有其他错误那多半是硬件层面触发了复位这时候晶振频率、电源纹波、主板供电都是排查对象软件堆栈再翻多少遍也没用。2. 系统级异常排查实操事件日志、安全日志与异常关机记录2.1 事件查看器怎么用才算会用很多人打开事件查看器看到满屏错误直接懵了不知道从哪下手。这里分享一个我自己的筛选方法不按来源排序而是按时间排序把异常发生的那个时间窗口框出来。比如用户反映“下午三点左右电脑卡死重启”那就筛选14:45到15:15之间的所有事件只留级别为“错误”和“严重”的条目逐条看来源和描述。系统日志里需要记住几个高频Event ID6008代表意外关机41是内核电源事件断电或崩溃后重启1001是Windows错误报告通常伴随蓝屏1074是系统进程发起的关机能看到是谁触发的。如果1074的触发方是“Windows\Winlogon”说明是用户主动关机如果是其他进程比如某个补丁安装程序或远程管理工具那就能顺藤摸瓜找到关机真凶。安全日志同样重要。想看异常关机、登录失败、权限异常用命令wevtutil qe Security /rd:true /c:20可以快速导出最近20条安全事件。图形界面里则是“Windows日志→安全”筛选4624登录成功、4625登录失败、4634注销。如果某个时间点有大量4625且登录类型是3网络登录那基本可以断定有人在爆破你的远程桌面或共享账号。2.2 异常关机日志与蓝屏dump解读“异常关机”这四个字看着简单但来源五花八门。我总结成三类断电类Event ID 41没有dump文件、蓝屏类Event ID 1001有小转储文件、强制关机类Event ID 6008。排查顺序也是按这个来先看有没有dump文件有dump直接分析没有dump优先查电源和散热有6008去查关机前后有没有计划任务或补丁安装。蓝屏dump文件的默认路径是C:\Windows\Minidump文件名类似051224-12345-01.dmp。分析工具有两个流派老牌的WinDbg需要配置符号表或者直接用微软的在线分析服务。我更推荐本地配一个WinDbg命令行一条!analyze -v就能给出蓝屏的触发模块和堆栈摘要虽然输出全是英文但里面的“MODULE_NAME”和“IMAGE_NAME”指到的文件就是嫌疑对象比如ntkrnlmp.exe内核、ndis.sys网卡驱动、dxgkrnl.sys显卡相关。还有一种情况是“看起来蓝屏但实际上没有dump”一般是开启了“自动重新启动”导致蓝屏一闪而过直接重启连写入转储文件的时间都不够。临时修复方法系统属性→高级→启动和故障恢复→取消勾选“自动重新启动”下次崩溃时就能定格在蓝屏画面抄下错误代码再去查对应的解决思路。2.3 Windows存储池掉盘的排查路径Windows存储池Storage Pool掉盘是个非常典型又让人头大的系统级异常。症状很明确池里的某个物理磁盘显示“降级”或“丢失”但磁盘本身用第三方工具检查又是好的。如果直接点“分离磁盘”或“删除”数据可能瞬间完蛋。正确的排查路径是先打开“服务器管理器→文件和存储服务→磁盘”看物理磁盘状态是“正常”还是“未初始化”如果是“未初始化”去磁盘管理看是否被系统标记为“脱机”右键“联机”后再回存储池刷新如果磁盘管理里能看到但存储池不认多半是磁盘签名冲突或者SATA/RAID控制器驱动异常。还有一个细节容易被忽略——存储池里的“写入高速缓存”和“自动精简配置”配合出问题。某些虚拟磁盘在物理盘掉线后I/O会持续卡住存储池状态一直显示“修复中”这时候直接重启机器反而可能触发元数据不一致。我的经验是先停下所有访问该池的应用再依次重启相关服务最后再考虑下线故障盘。怀疑硬件问题时用Get-PhysicalDisk | ft FriendlyName,HealthStatus,Usage,OperationalStatus查看每个物理盘的健康状态比图形界面直观得多。2.4 驱动异常实例8852CE无线网卡频繁断连8852CE这个Realtek无线网卡芯片在很多中低端笔记本上都有Win11下的断流问题几乎成了玄学。我处理过多个案例现象都一样Wi-Fi连接正常但每隔几分钟断一次事件日志里隔三差五出现“WLAN-AutoConfig”来源的Event ID 5007或8002。这类驱动异常有一个通用的排查顺序第一步设备管理器找到网卡右键属性→详细信息→硬件ID确认芯片型号第二步查当前驱动版本去官网找对应版本对比第三步用netsh wlan show interfaces看连接信号质量如果信号强度低于-70dBm先考虑信道干扰第四步在设备管理器里关掉“允许计算机关闭此设备以节约电源”这个选项在电源管理页签下默认勾选经常导致网卡休眠后无法唤醒。如果上面的步骤都做了还是断尝试固定无线信道和频段带宽不要用自动。很多双频路由器的自动切换策略和这块网卡驱动配合不佳固定5G信道后问题直接消失。最后的手段是禁用再启用网卡相当于软复位这个操作偶尔能救急但不能根治。3. 网络层异常排查IP冲突、SMB共享与端口冲突3.1 IP冲突排查一条命令定位IP地址冲突在办公环境里几乎每天都有症状是电脑时不时弹窗“网络地址冲突”或者一个设备能上外网另一个不能。很多人遇到IP冲突第一反应是改IP但改完第二天又冲突因为没有找到冲突源。排IP冲突的正确姿势是先把本机IP改成其他不冲突的地址然后用arp -a看看局域网里有哪些IP和MAC对应关系再用ping 冲突的IP或者直接扫整个网段找出占用了同一IP的设备。如果你在公司网络里没有扫描工具最快的方法是把冲突IP留空用arp -a看到该IP对应了哪个MAC再去路由器后台查这个MAC是哪台设备。如果是DHCP环境下的IP冲突重点排查两类手动指定了静态IP的设备以及路由器DHCP地址池设置过小。前者好办改掉静态IP后者需要在路由器上扩大地址池范围。还有一种特殊情况是Windows的随机硬件地址功能导致IP漂移网络共享打印机时特别常见在Wi-Fi属性的“随机硬件地址”里关掉即可。3.2 共享文件夹访问失败协议、账号、网段三步走共享文件夹访问失败是Windows网络异常里最高频的问题经常有人在群里先甩一句“是不是SMB协议没开啊”。这句话说对了一半SMB确实是共享访问的核心协议但大多数共享打不开的场景SMB服务本身并没有问题而是卡在账号认证、网络发现、防火墙这几个环节。我的排查顺序固定为三步第一步ping对端IP不通先解决连通性通了进第二步第二步用net use \\主机名\共享名 /user:用户名 密码手动建立连接这一步能直接暴露账号密码或策略问题最常见报错是“发生系统错误 5”拒绝访问和“发生系统错误 53”找不到网络路径第三步检查SMB服务状态在双方的“Windows服务”里看Server和Workstation服务是否启动再看防火墙是否放行了445端口。很多老机器还会出现“指定网络名不再可用”这种情况多半是SMB协议版本不匹配。Windows Server 2025、Windows 11工作站默认开启了SMB 3.1.1而一些老设备或精简版系统只支持SMB 1.0。在服务端启用SMB 1.0的支持控制面板→程序→启用或关闭Windows功能→SMB 1.0/CIFS文件共享支持可以解决但要注意SMB 1.0的安全性极差只建议临时开启并用完即关。3.3 端口占用与“关闭端口号”的正确姿势“Windows如何关闭端口号”是很多人搜过的问题但这个问题本身就有歧义。端口不是拿来“关闭”的而是某个进程在监听它真正要做的是找到监听端口的进程并停掉它或者配置防火墙阻断外部访问。排查端口占用用两条命令netstat -ano | findstr :8080能看到LISTENING状态和对应PID然后tasklist | findstr PID把PID翻译成进程名。如果进程名是java.exe、python.exe这类说明是开发环境占用了端口如果是svchost.exe或SystemPID为4则要小心这是Windows内核和系统服务的端口。PID为4System进程占用80端口的情况很经典因为HTTP.sys默认会占用80端口IIS或某些系统组件会用到。想释放这个端口先停掉依赖它的服务比如World Wide Web Publishing Service再用netsh http show servicestate查看当前被HTTP.sys占用的URL和进程。还有一种粗暴但有效的做法是在防火墙高级设置里新建入站规则阻止特定端口的外部访问这样即使进程在监听外部也连不上适合对内对外开放的端口做临时管控。3.4 网络异常990002与422通信故障排查思路“网络异常990002请使用正确网段的网络”这类报错常见于企业级准入客户端或老旧的网管软件。表面意思是客户端检测到你当前不在正确的网段里实际上背后的原因五花八门电脑同时插了有线和无线导致路由冲突、本机IP和准入系统要求的IP段不一致、设备没有正确获取DHCP地址、甚至是系统时间不对导致认证失败。排这种网络异常的通用思路是先看ipconfig确认当前IP是自动获取还是静态指定然后看是否有多个网卡同时启用再看DNS服务器是否是准入系统要求的地址最后检查认证服务主机的连通性。如果ipconfig里IP地址是169.254.x.x说明DHCP服务器没响应优先排查网线和交换机端口而不是和准入系统纠缠。“422通信故障”在Windows客户端软件的报错语境里多半是业务接口调用返回了422状态码Unprocessable Entity语义错误或请求格式不对。排查时不要盯着“通信故障”四个字而是去日志里抓接口的请求和响应体比对请求参数是否缺失、格式是否合法。如果日志抓不到用Fiddler或Wireshark抓包看HTTP层响应只要能看到422状态码和错误描述问题就锁定在服务端的参数校验或客户端的序列化逻辑和底层网络没有半毛钱关系。4. 应用与开发环境异常命令行、JDBC与部署类问题4.1 Windows脚本命令闪退与终端进程启动失败脚本命令闪退是最磨人的Windows问题之一特别是bat脚本双击直接闪退连错误信息都看不见。我见过有人反复重写脚本结果问题根本不在脚本逻辑。最简单的临时诊断方法不要双击运行打开cmd窗口把脚本拖进命令行回车执行这样脚本崩溃后窗口不会关闭错误信息会留在屏幕上。如果脚本确实一闪而过且无输出在脚本结尾加一行pause也可以但治标不治本根治仍要找到报错点。另一个高频问题是“终端进程启动失败启动期间发生本机异常”错误信息里还提到“无法启动conpty”或“已移除winpty”。这个现象常见于VSCode的终端、Windows Terminal以及通过SSH连接Windows后运行的交互式程序。根因是Windows的伪终端组件ConPTY与终端程序不兼容或者当前终端会话的socket路径异常。解决办法通常是关闭终端进程在服务里重启“Windows Terminal Service”或重启电脑如果用的是VSCode设置里搜terminal.integrated.defaultProfile把默认终端从PowerShell改成Command Prompt试试老方案是用winpty来包装程序但winpty和ConPTY经常互相打架建议优先走“检查终端版本更新到最新版”这条路。换行异常也是脚本问题的重灾区。从Linux服务器拷贝过来的shell脚本或配置文件在Windows下打开往往会变成一行原因就是LF换行符被Windows按CRLF处理。用Notepad或VSCode右下角切换行尾序列或者在git里配置core.autocrlf false都能避免这种问题。4.2 Windows上启动Elasticsearch的常见坑很多人在Windows上折腾Elasticsearch启动失败日志报“ElasticsearchException: java.io.IOException: Failed to bind to [9200]”或者“requires Java 17”。这背后其实是两个独立的坑。第一个坑是端口被占。Elasticsearch默认监听9200和9300经常和已有的服务冲突。排查命令还是netstat -ano | findstr 9200如果被占用但不想改端口在config/elasticsearch.yml里改掉http.port和transport.port即可。第二个坑是JVM版本不对。新版Elasticsearch对JDK版本要求严格ES 8.x要求JDK 17ES 7.17可能要求JDK 11装错JDK启动直接报异常。Windows上还有一个特有的坑路径里包含空格或中文会导致启动失败。比如把Elasticsearch解压到C:\Program Files\目录下启动脚本会找不到JAVA_HOME或数据目录。解决方案是解压到一个无空格纯英文路径比如D:\es\elasticsearch-8.13.0。还有个容易被忽略的点是Elasticsearch默认不允许以管理员身份运行如果你用管理员权限的PowerShell执行elasticsearch.bat会报“can not run elasticsearch as root”这个换普通用户执行即可。如果想通过脚本或服务方式后台运行Elasticsearch记得先配置好elasticsearch.yml里的network.host和discovery.seed_hosts否则服务启动后又自动退出日志还显示“master not discovered yet”。这些报错信息虽然长但每一条都指向明确配置项顺着改就行。4.3 JDBC连接器异常与Java数组越界先说JDBC连接器异常。在Windows上跑Flink、Spark或普通Java应用遇到java.sql.SQLException: No suitable driver found for jdbc:mysql://...是最常见不过的问题。这句报错往往不是真的“没有驱动”而是ClassLoader没加载到驱动类或者驱动包版本和你用的JDK不兼容。排查思路先把mysql-connector-java.jar放到应用的lib目录确认版本是8.x还是5.xMySQL 8以上必须用8.x驱动然后用Class.forName(com.mysql.cj.jdbc.Driver)显式加载老版本驱动类名则是com.mysql.jdbc.Driver用错类名照样报错。JDBC连接还会出现“Communications link failure”在Windows上可能是防火墙拦了3306端口或者MySQL的bind-address配置成了127.0.0.1只允许本机连接。先用Test-NetConnection IP -Port 3306确认端口通不通再检查MySQL的my.ini把bind-address改成0.0.0.0重启服务。Java数组越界异常ArrayIndexOutOfBoundsException本身不是Windows问题但在Windows上跑批处理任务时特别容易触发比如读取某个目录下的文件列表后按索引取值Windows的目录枚举顺序和Linux完全不一样文件顺序不稳定就会导致数组越界。这种问题与其说是数组问题不如说是代码里对列表顺序有隐含假设。建议在代码里不要依赖文件枚举顺序或者在Windows环境里用files.sort(Comparator.comparing(...))显式排序。日志里看到异常栈之后先看是主线程还是子线程抛的再看是哪个List或数组下标越界绝大多数时候是边界判断少了一个“长度减一”的条件。4.4 SQL Server服务进程异常终止排查老项目里SQL Server 2000“服务进程被异常终止无法继续提供服务”这种报错今天看着像古董但银行、工厂的老系统里存量依然不少。这类进程异常终止第一步永远是查SQL Server的错误日志C:\Program Files\Microsoft SQL Server\MSSQL\LOG\ERRORLOG文件尾部就是崩溃前的现场。SQL Server进程被终止常见原因有四类外部进程杀掉杀软误杀sqlservr.exe、内存严重不足Windows无法提交内存页面数据库服务被系统回收或崩溃、日志文件损坏事务日志膨胀后磁盘满、系统强制重启Windows Update或电源策略导致。如果是杀软误杀把SQL Server的安装目录和数据目录加白名单如果是内存不足检查Windows虚拟内存设置给系统盘C盘分配足够的页面文件如果是日志损坏用DBCC CHECKDB扫描库同时备份数据目录下所有文件和日志。对于新版本的SQL Server服务异常终止后在Windows事件日志里通常能找到Event ID 17052或17182对应SQL Server自己的错误日志条目。处理完根因后记得把SQL Server启动模式改成“自动”并设置“服务失败后自动重新启动”选项至少能保证下次异常时不至于服务一直停摆。4.5 在Windows上部署GPU加速模型的环境异常AI模型部署已经越来越多地跑到Windows上比如用GPU Stack这类工具把模型部署在Windows环境里“模拟线上”但Windows的GPU栈坑远比Linux多。最常见的报错是CUDA版本和驱动版本不匹配日志里写“CUDA driver version is insufficient for the CUDA runtime version”——翻译成人话显卡驱动太老但CUDA工具包想用新功能。排这类问题不要急着重装CUDA先看两个数字驱动支持的CUDA版本nvidia-smi输出的右上角以及你项目里引用的是哪个CUDA runtime版本。驱动版本必须大于等于runtime版本要求。第二个高频坑是Windows下GPU显存被桌面窗口占住现象是模型加载时报“out of memory”明明显卡显存看着够。Windows桌面、浏览器硬件加速、远程桌面会吃掉一部分显存排查方法是关掉浏览器等占用显存的应用或者在环境变量里设置CUDA_VISIBLE_DEVICES强制指定某张卡。第三个坑是进程级资源限制。Windows默认不会像Linux那样报“cannot allocate memory”但你要部署多个模型实例时会莫名出现初始化失败。这时候用nvidia-smi确认单卡显存占用把不必要的进程清掉同时注意GPU Stack这类工具在Windows上需要管理员权限才能访问GPU性能计数器非管理员运行会报性能监控初始化失败以管理员身份重跑即可。5. 线上服务器CPU 100%定位链路复盘5.1 确认进程别一上来就查代码线上服务器CPU直接拉满这是每一个做过运维的人都经历过的恶梦。我的第一反应永远不是去翻代码而是先花三十秒确认CPU是被哪个进程吃掉的。打开任务管理器切到“详细信息”选项卡点击CPU列排序。如果是Windows Server可以用组合键CtrlShiftEsc打开任务管理器或者用命令行tasklist配合wmic看进程的CPU时间。这里有第一个坑双核以上的机器任务管理器默认显示的是CPU总体使用率一个进程在多核机器上占满单核总CPU也才20%左右但你会觉得“服务器卡死了”。所以一定要在任务管理器里把CPU列切换成“按核心数折算”或者用资源监视器resmon勾选进程看每个核心的分配情况。确定进程名之后分两类走进程是已知业务比如java.exe、python.exe直接跳到下一步深入线程进程是未知可疑进程先确认是不是被恶意软件伪装了。右键进程打开“打开文件所在位置”看路径是不是系统目录可以快速判断。遇到可疑路径先用任务管理器检查CPU占用再用杀毒工具扫描不要手工杀进程了事。5.2 深入线程perfmon与Process Explorer确认了是java.exe还是sqlservr.exe占CPU之后下一步要定位到具体线程。任务管理器能看到进程但看不到线程。这时候用Performance Monitorperfmon或者Sysinternals的Process Explorer都是好选择。在Process Explorer里双击进程点“Threads”标签能看到每个线程的CPU占用率和线程ID。CPU占用最高的线程记录下来线程ID就是接下来抓dump和分析的关键线索。如果不方便装GUI工具PowerShell也可以Get-Process -Name java | Select-Object Id,CPU,Threads能拿到进程基本信息但要看到线程级CPU需要启用性能计数器。还有一种情况是CPU占用忽高忽低无法稳定复现峰值。这时推荐用perfmon建计数器日志Processor(_Total)% Processor TimeProcess()% Processor TimeThread()% Processor Time采样间隔设5秒连续采集半小时。等下一次CPU飙升时回看日志定位到具体进程和线程。Windows自带的perfmon日志功能强大但界面繁琐满足日常排查足够。5.3 抓dump看调用栈拿到线程ID之后接下来要回答的问题是这个线程在干什么。最专业的做法是抓一个进程转储dump文件然后看调用栈。Windows上有现成的工具procdumpSysinternals套件里的可以用procdump -ma -o -accepteula -n 3 -s 10 java.exe dump抓三次dump间隔10秒。如果要求更精准用-t参数指定线程ID只抓对应线程的dump。dump文件抓到后WinDbg或者Visual Studio打开!analyze -v自动分析如果是Java进程更直接的方式是jstack PID抓线程快照看线程状态和堆栈能直接看出是在GC、等锁还是无限循环。实际案例里CPU 100%的代码层原因无外乎四种死循环、内存不断分配导致GC风暴、线程自旋等待、正则或序列化的灾难性回溯。抓完dump看到堆栈集中在某个类名上八成就是该类的某段代码有问题。有一次我排查到某服务CPU飙高dump里全是同一个类的方法调用查代码发现是一个while循环处理队列时条件判断逻辑写反了哨兵一直没变化导致死循环。这就是dump的价值几秒钟定位省去几小时的猜谜。5.4 我踩过的两个判断误导CPU排查中经常有两个误导方向我简单提醒一下。第一个误导是“CPU高总是代码问题”。曾经有一台服务器CPU持续60%按代码思路查了半天最后发现是Windows Defender在后台做全盘扫描大量的文件I/O导致系统CPU和磁盘都高。排查CPU占用的时候除了看用户态CPU还要看中断、DPC、系统进程占用。如果是System进程CPU高优先怀疑驱动和硬件常见原因是网卡驱动问题导致大量中断用perfmon的Processor Information(_Total)% Interrupt Time确认。如果是本机杀毒软件Defender、第三方AV占CPU可以调整实时保护的扫描调度或者把业务目录加入白名单。第二个误导是“CPU高就盲目杀进程重启”。有一次线上服务CPU飙高现场值班同学直接重启了进程结果确实恢复正常了但不到半小时又飙高。因为没有保留诊断数据重启等于销毁了现场后面只能靠猜。正确的操作是遇到CPU异常先抓CPU占用快照和dump再决定要不要重启。哪怕进程马上要杀也先用tasklist /v把当前进程的命令行参数记录下来这样重启之后还能恢复原状而不是稀里糊涂地裸启动一个实例。6. 汇总一套自己的排查工具箱6.1 日志优先原则日志优先是我所有排障经验里最核心的一条原则。无论面对什么Windows异常先花十分钟把相关日志完整看一遍比盲目操作三天都有效。事件查看器是Windows的第一层日志应用自身的工作目录下的log文件是第二层日志把两层日志按时间对齐异常的脉络就出来了。有人问业务应用没有日志怎么办那就先让它“会输日志”。临时给应用装一个日志输出框架比如Java的log4j、.NET的Logging或者用系统层面的工具补足ProcMonProcess Monitor可以监控某个进程的文件、注册表、网络活动Process Explorer可以看句柄和线程栈。这些工具比纯改代码更快。6.2 时间线还原法第二常用的方法是时间线还原。Windows异常很少是凭空冒出来的在这之前一定有一系列前置动作昨天装了某个驱动、下午改过防火墙规则、凌晨跑过批量任务。把这些动作按时间列出来异常点前后一对照八成问题就浮出水面。时间线还原操作起来不复杂事件查看器按时间筛选早期事件看有没有补丁安装记录Event ID 19、43、驱动安装记录Event ID 20001、20002、应用安装记录Event ID 11707。如果发现异常前的确有系统更新优先用wusa /uninstall /kb:5000000卸载对应补丁验证如果有驱动更新去设备管理器回退驱动版本。这比翻遍所有论坛帖子都有效。6.3 常用工具清单最后整理一份我压箱底的Windows排查工具清单按使用频率排序Windows自带的工具就不再多说事件查看器、资源监视器、性能监视器、任务管理器永远是第一梯队。Sysinternals套件里的Process Explorer、ProcMon、Autoruns、procdump是我处理疑难杂症时几乎必开的一套工具官方出品既安全又全面。PowerShell命令wmic、Get-WinEvent、Get-Process日常查询效率比图形界面高很多。网络层有Test-NetConnection、netstat、route、arp、ping、telnet这些基础命令。复杂的抓包场景再上Wireshark。如果涉及系统文件完整性sfc /scannow和dism /online /cleanup-image /restorehealth都要会用Windows系统文件损坏时这两个组合拳能救活很多半死不活的系统。最后分享一点个人习惯每次排障时把时间线、命令输出、日志截图集中存成一个文档标上行号和时间。下次再遇到类似问题直接翻这个文档两个小时的工作常常压缩成十分钟。Windows异常永远出不完新花样但万变不离其宗日志、时间线、工具三件套拿稳多数问题都能在半小时内把范围缩到最小剩下的就是耐心读日志、读栈、读代码的事了。
返回列表