5分钟定位法 · 手把手排查 · 命令速查 · 应急止血 · 根因分析
线上出问题,第一反应不是查原因,而是先止血!遵循"先恢复服务,再排查根因"原则。
止血优先原则:先恢复服务再查原因!不要在用户还挂着的时候慢慢 debug。服务恢复了,再回头分析 dump 和日志。
| 手段 | 适用场景 | 操作 | 风险 |
|---|---|---|---|
| 重启 | 进程假死、内存泄漏 | kill -9 + 自动拉起 | 丢失现场,先 dump 再杀 |
| 回滚 | 新版本引入的 bug | git revert + 重新部署 | 低风险,推荐优先尝试 |
| 限流 | 流量突增压垮服务 | Nginx限流 / Sentinel | 部分用户受影响 |
| 降级 | 非核心功能拖垮主流程 | 关闭非核心接口 | 功能暂时不可用 |
| 切流量 | 单机房故障 | DNS / LB 切到备用机房 | 需要多机房部署 |
应急响应就像急诊:先止血(恢复服务)→ 再检查(定位原因)→ 最后根治(修复上线)。不要在病人还在出血的时候做全身检查!
| 原因 | 特征 | jstack表现 | 解决方案 |
|---|---|---|---|
| 死循环 | 单个线程 CPU 100% | 线程一直停在某个 while 循环 | 修复循环退出条件,加最大次数限制 |
| 正则回溯 | CPU突增,请求含特殊字符 | 停留在 Pattern.matcher / Regex | 换用预编译正则,避免贪婪匹配,限制输入长度 |
| 频繁 Full GC | 多个GC线程CPU高 | GC线程频繁出现 | jstat -gcutil 确认 → 扩堆/优化对象创建/排查内存泄漏 |
| 加密/序列化操作 | 批量任务时CPU高 | 停留在加密/序列化代码 | 异步处理、限制批量大小、用更快的算法 |
| 线程池满 | 大量线程同时活跃 | 线程数远超预期 | 调优线程池参数、排查线程泄漏、拒绝策略 |
快速判断:top 看到高 CPU 后,先 jstat 看一眼 GC 频率。如果 FGC 一秒好几次,大概率是 GC 问题而不是代码问题。
| 原因 | 表现 | MAT特征 | 解决方案 |
|---|---|---|---|
| ThreadLocal 泄漏 | 堆内存持续增长 | ThreadLocalMap 中大量 Entry | 用完 remove();线程池场景尤其注意 |
| 集合无限增长 | HashMap/ArrayList 越来越大 | 某个 Map 实例占内存最大 | 加容量上限(LRU),定期清理,检查 only-add-no-remove |
| 大对象查询 | 单次查询返回几万条数据 | 大量业务对象实例 | SQL 加 LIMIT,分页查询,流式处理 |
| Metaspace 满 | java.lang.OutOfMemoryError: Metaspace | 加载的类数量异常多 | 加大 -XX:MaxMetaspaceSize,排查动态代理/CGLIB |
| 直接内存泄漏 | 堆内存正常但进程 OOM | NIO DirectByteBuffer 相关 | 检查 ByteBuf 是否 release,调整 -XX:MaxDirectMemorySize |
关键操作:线上 OOM 时,先 jmap -dump 导出堆快照,再重启!重启后现场就没了,没有 dump 就无法定位原因。dump 文件一般很大,注意磁盘空间。
| 类型 | 路径示例 | 清理方法 |
|---|---|---|
| 日志文件 | /var/log/app/*.log | 配置 logback 滚动策略,保留 N 天;用 logrotate |
| Docker 镜像 | /var/lib/docker/ | docker system prune -a;清理 <none> 镜像 |
| 临时文件 | /tmp/* | 定期清理;代码中确保 finally 里删临时文件 |
| 数据库 binlog | /var/lib/mysql/mysql-bin.* | 设置 expire_logs_days=7;PURGE BINARY LOGS |
| GC 日志/dump | /data/logs/gc.log, *.hprof | 定期归档清理;hprof 分析完就删 |
| Nginx 日志 | /var/log/nginx/ | 配置 logrotate,压缩旧日志 |
注意:删除日志文件后如果磁盘空间没释放,说明有进程还在写入。用 lsof | grep deleted 找到这些进程,重启它们才能释放空间。或者用 > file.log 清空文件内容而不是删除文件。
| 问题 | 现象 | 排查思路 | 解决方案 |
|---|---|---|---|
| 缓存雪崩 | 大量 key 同时过期,请求全打到 DB | 看 DB 连接数是否突然飙升;检查 key 过期时间是否集中 | 过期时间加随机偏移(TTL + random);多级缓存;互斥锁重建 |
| 缓存穿透 | 查询不存在的数据,缓存没命中,DB 也没命中 | 看请求的 key 是否合理;是否有恶意请求 | 布隆过滤器拦截;缓存空值(TTL 短);参数校验 |
| 缓存击穿 | 热点 key 过期瞬间,大量请求打到 DB | 看是否某个热点 key 刚好过期;监控该 key 的 QPS | 热点 key 永不过期;互斥锁(只放一个请求回源);提前异步刷新 |
经验法则:Redis 内存使用率超过 80% 就要开始关注。配置好 maxmemory 和淘汰策略,避免 Redis 被 OOM killer 杀掉。线上永远不要用 KEYS 命令,用 SCAN 代替。
| 方案 | 操作 | 适用场景 |
|---|---|---|
| 增加消费者 | 紧急扩容消费者实例数 | 临时流量高峰,消费能力不足 |
| 临时扩容 | 增加 partition + 消费者线程 | Kafka 场景,partition 数是消费并行度上限 |
| 跳过非核心消息 | 将非核心消息转发到"待处理"队列延后消费 | 核心链路消息优先,非核心可以先跳过 |
| 降级消费逻辑 | 临时简化消费逻辑(如跳过发短信等非必要步骤) | 消费逻辑太重导致处理慢 |
注意:消息积压恢复时,消费速率可能飙升,瞬间打爆下游数据库或接口!务必加上消费限流,宁可多积压一会儿,也不要引发更大的故障。
一张表涵盖所有常见问题的排查命令、关注指标和常见原因。
| 问题类型 | 排查命令 | 关注指标 | 常见原因 |
|---|---|---|---|
| CPU飙高 | top → top -Hp → printf '%x' → jstack | CPU使用率、线程堆栈 | 死循环、正则回溯、频繁FullGC、加密操作 |
| 内存溢出 | jmap -histo → jmap -dump → MAT分析 | 堆内存使用、对象数量 | ThreadLocal泄漏、集合无限增长、大对象查询 |
| GC频繁 | jstat -gcutil → GC日志 | FGC次数、OGC使用率、GC停顿时间 | 堆太小、内存泄漏、大对象频繁分配 |
| 磁盘满 | df -h → du -sh * → find -size → lsof | 分区使用率、大文件、已删除未释放 | 日志文件、Docker镜像、binlog、临时文件 |
| 网络超时 | ping → telnet → traceroute → iptables | 连通性、端口、路由、防火墙 | 防火墙规则、DNS问题、路由不通、服务未监听 |
| DNS问题 | nslookup → dig → /etc/resolv.conf | 解析结果、DNS服务器配置 | DNS配置错误、DNS缓存、域名过期 |
| TCP连接过多 | ss -ant → ss -s → netstat | TIME_WAIT数量、连接状态分布 | 短连接太多、未设置SO_REUSEADDR、内核参数未调优 |
| 慢查询 | slow_query_log → EXPLAIN → SHOW PROFILE | 查询耗时、扫描行数、索引使用 | 缺索引、全表扫描、SQL写法差、数据量暴增 |
| 数据库死锁 | SHOW ENGINE INNODB STATUS → INNODB_LOCK_WAITS | 锁链、等待关系、涉及SQL | 加锁顺序不一致、事务范围太大、并发更新同一行 |
| 连接池满 | SHOW PROCESSLIST → SHOW STATUS | 当前连接数、最大连接数、Sleep连接数 | 连接泄漏、慢查询占连接、连接池配置太小 |
| 主从延迟 | SHOW SLAVE STATUS | Seconds_Behind_Master、IO/SQL线程状态 | 大事务、从库配置低、网络延迟、从库跑报表 |
| Redis慢 | SLOWLOG GET → redis-cli --bigkeys | 慢日志、BigKey、内存使用 | BigKey、复杂命令、KEYS *、内存满频繁淘汰 |
| Redis内存满 | INFO memory → CONFIG GET maxmemory-policy | used_memory、碎片率、淘汰策略 | 没设过期时间、BigKey、淘汰策略不对 |
| MQ消息积压 | kafka-consumer-groups --describe / rabbitmqctl list_queues | Lag数量、消费速率、消费者数量 | 消费者挂了、消费逻辑慢、生产速度暴增 |
| 接口超时 | grep ERROR 日志 → traceId链路追踪 | RT分布、错误率、下游响应时间 | 下游慢、数据库慢查询、线程池满、GC停顿 |
这份速查表建议保存到手机或打印出来贴工位上。线上出问题时,先查这张表找到对应的排查命令,比百度搜索快 10 倍。