⚙️ 故障排查与解决
这类问题模拟线上真实故障,是面试的重中之重。面试官旨在考察你的技术广度 (能否想到所有可能性)、排查逻辑 (是否有一套科学的方法论)和问题深度(能否定位到根本原因)。
-
典型问题:
-
"一个网站突然访问很慢,你如何一步步定位问题?"
-
"线上服务器CPU使用率100%怎么办?"
-
"API接口挂了或网页无法访问,如何处理?"
-
-
回答要点 :展现你的排查方法论 。可以按照"监控确认 -> 链路分析 -> 分段排查"的思路,比如:先查看基础监控(CPU、内存、磁盘IO、网络),再检查应用状态(服务进程、日志报错),最后深入网络、中间件、数据库等。使用
top、vmstat、iostat、netstat等命令分析系统状态。
一个网站突然访问很慢,你如何一步步定位问题?排除了系统,网络,配置,带宽,攻击。还有什么会导致这个故障;
📊 监控确认:快速定位问题方向
首先,应依据现有的监控系统进行初步判断,这能帮助你快速明确排查方向。
-
查看资源监控 :登录云服务器控制台或使用内部监控工具(如Zabbix、Prometheus),检查服务器的 CPU使用率 、内存占用 、磁盘I/O (特别是读/写等待时间)和网络带宽 使用情况。任何一项指标接近或达到瓶颈,都可能是问题的直接原因。
-
分析业务监控 :关注 Web服务器(如Nginx/Apache)的请求吞吐量 、响应时间 ,以及数据库的活跃连接数 、慢查询数量 等关键业务指标。一个突然的飙升或下降都值得警惕。
-
确认问题范围:通过监控或快速询问,判断问题是全局性的(所有用户都慢),还是仅影响特定地域或运营商的用户。这有助于初步区分是源站问题还是网络链路问题。
🔍 链路分析:追踪数据包路径
如果监控显示服务器资源正常,那么问题可能出在用户到服务器的网络链路上。
-
使用
ping命令 :从客户端或同地域的测试机向服务器公网IP发送ping包,观察延迟(time值) 和丢包率(lost)。高延迟或持续丢包通常意味着网络链路不稳定。 -
使用
traceroute(Linux) 或tracert(Windows) 命令:该命令可以显示数据包经过的每一跳(网络节点)。观察在哪个节点之后延迟突然增加或出现超时,这有助于定位到具体的网络故障点。 -
检查DNS解析 :使用
dig或nslookup命令查询域名解析。DNS解析缓慢会直接延长整个页面的加载时间。可以尝试直接使用服务器IP地址访问网站,如果速度正常,则很可能是DNS解析的问题。
⚙️ 分段排查:从后端到前端的深度检查
当排除了宏观资源问题和网络链路问题后,就需要对网站架构的每一层进行精细排查。
排查阶段:服务器层面
关键检查点:检查系统日志(如 /var/log/messages)、Web服务器错误日志(如Nginx的error.log),查找OOM(内存溢出)错误、文件句柄耗尽等异常。
常用命令/工具:journalctl, dmesg, top, vmstat, iostat
排查阶段:应用层面
关键检查点:分析数据库慢查询日志,优化低效SQL;检查应用代码是否存在性能瓶颈,如未优化的循环、锁竞争;确认缓存(如Redis, Memcached)是否失效,导致大量请求直接穿透到数据库。
常用命令/工具:SHOW PROCESSLIST, EXPLAIN, 应用性能管理(APM)工具
排查阶段:前端层面
关键检查点:利用浏览器开发者工具(F12),切换到 Network(网络) 面板,刷新页面。这里会详细列出每个资源(图片、JS、CSS文件)的加载时间和大小。重点关注加载耗时最长或体积过大的资源。
常用命令/工具:Chrome DevTools (F12)
❓ 排除常见原因后的其他可能性
如果已经排除了系统资源、网络、配置、带宽和攻击这些常见因素,那么以下这些相对隐蔽的原因值得你深入探究:
-
第三方服务或脚本拖慢 :网页中嵌入的第三方工具,如在线客服、统计分析代码(Google Analytics)、社交媒体插件等,如果这些服务的服务器响应慢,会阻塞整个页面的渲染。
-
缓存失效或预热不足 :CDN缓存 如果因为配置不当或缓存键设置问题导致命中率突然暴跌,大量回源请求会压垮源站。同样,应用层缓存(如Redis)如果大面积失效(或未预热),会导致数据库瞬时压力激增。
-
资源竞争或后台任务 :服务器上可能运行着你未察觉的定时任务(cron job) 或后台程序(如日志切割、数据备份、系统更新)。这些任务在特定时间点会消耗大量CPU、内存或磁盘I/O资源,与Web应用产生竞争,导致网站访问变慢。
-
前端资源或代码问题 :可能是近期的一次代码变更导致的,例如:引入了未压缩的大型图片或脚本 、出现了错误的资源引用 (加载不存在的图片或文件)、或 JavaScript 执行效率低下 阻塞了页面渲染。
线上服务器CPU使用率100%怎么办?
🔍 四步定位法
核心的排查路径可以概括为四个步骤:定进程 → 定线程 → 转进制 → 定代码 。
-
定进程:找到消耗CPU最高的进程
在服务器上执行
top命令,然后按P键,使进程列表按CPU使用率从高到低排序。排在第一位的通常就是导致问题的进程,记录下它的 **PID(进程ID)** 。 -
定线程:找到进程内消耗CPU最高的线程
执行
top -Hp <PID>命令(将<PID>替换为上一步找到的进程ID)。这个命令会显示该进程内所有线程的资源占用情况。同样按P键排序,找到消耗CPU最高的线程,记录下它的 **TID(线程ID,十进制)** 。 -
转进制:将线程ID转换为十六进制
Java堆栈信息中的线程ID是十六进制格式的,所以需要转换。使用命令
printf "%x\n" <TID>,将十进制的TID转换为十六进制,并记录下来 。 -
定代码:定位问题代码行
使用
jstack命令打印当前进程的线程堆栈信息,并与上一步得到的十六进制线程ID进行匹配。命令为jstack <PID> | grep <十六进制TID> -A 20。这个命令会输出该线程当前的执行堆栈,你可以在其中找到具体的类名、方法名和代码行号,这里就是导致CPU飙升的"罪魁祸首" 。
🧠 常见根因与解决方案
定位到代码后,通常会发现以下几类问题:
| 问题类型 | 具体表现/原因 | 解决思路 |
|---|---|---|
| 计算密集型任务 | 线程处于 RUNNABLE 状态,可能是出现死循环 、复杂算法 或无限递归 。 |
优化算法逻辑,为循环添加可中断机制 (如volatile标志位)或执行次数上限 。 |
| 频繁GC | 消耗CPU的线程名是 GC Task Thread 。使用 jstat -gcutil <PID> 间隔 次数命令会发现 **FGC(Full GC次数)** 很大且持续增长 。 |
结合 jmapdump内存,分析是否存在内存泄漏 或大对象分配,优化JVM参数 。 |
| 锁竞争/死锁 | 大量线程处于 BLOCKED 状态 。或在 jstack日志中直接搜索 **deadlock** 关键字会提示死锁信息 。 |
缩小锁粒度 ,使用无锁数据结构 或尝试使用 tryLock等非阻塞式锁 。对死锁进行代码重构,保证加锁顺序一致。 |
| 数据库服务器 | 如果是数据库(如MySQL)CPU高,应排查是否有慢查询SQL 或QPS/TPS突增 。 | 查看数据库慢查询日志,对SQL进行优化或增加索引 。如果是正常流量增长,考虑限流降级 或扩容 。 |
💡 实用技巧与安全防护
-
善用脚本:可以将上述排查步骤写成Shell脚本,在故障发生时一键执行,快速定位 。
-
安全排查 :如果发现未知的、奇怪的进程占用大量CPU,需要警惕服务器是否被植入挖矿病毒或木马。可使用安全工具进行扫描,并检查异常的网络连接和系统进程 。
-
资源竞争 :使用
vmstat 1命令,如果发现cs(上下文切换) 指标过高(如每秒超过10万次),可能是线程创建过多或锁竞争激烈导致的资源竞争 。 -
I/O等待 :在
top命令的输出中,如果%wa(I/O等待) 指标很高,说明CPU时间大量花在等待磁盘I/O上。此时应使用iostat等工具进一步排查磁盘性能问题 。