这是一个 很典型的微服务性能问题,服务间调用突然变慢可能是由多个维度导致的。在分布式环境下排查这种问题需要系统性地分析,以下是一个 逐步排查指南,帮你从“可能性”缩小到“真问题”。
🚨 一、确认问题现象
- 是“所有调用”都慢,还是“某个接口”慢?
- 是“持续慢”还是“偶发慢”?
- 客户端是否有超时日志?服务端是否有慢请求日志?
🔁 一、持续慢(持续性高延迟)
🧠 特征:
- 所有请求 从某一时刻开始就一直很慢
- 重启无效,多个节点都慢
- 接口响应时间稳定在一个高值
🧨 常见原因:
类别 | 原因 |
---|
服务端 | 代码变更引入性能问题、慢 SQL、线程池打满 |
数据库 | 查询慢了、索引失效、数据量激增 |
网络 | 长连接泄漏、网关配置错误、负载均衡不均 |
系统 | JVM GC 频繁、内存不足、磁盘 IO 问题 |
🔍 排查建议:
- 版本回退测试:新部署版本?先怀疑上线代码
- CPU/MEM/GC 检查:top + jstat + jmap
- 慢 SQL 日志:数据库是否背锅
- 链路追踪查看瓶颈节点
- 排查线程池是否打满(线程泄漏)
- 是否大量请求打在某一个节点上(LB 均衡问题)
🌩 二、偶发慢(间歇性高延迟)
🧠 特征:
- 大多数请求正常,只有少部分“突然慢一下”
- 间隔时间不规则,有时还正常
- 重试可能就好了
🧨 常见原因:
类别 | 原因 |
---|
网络 | 网络抖动、DNS 解析慢、请求路由错乱 |
GC | 老年代 Full GC 突然触发(瞬时卡顿) |
数据库 | 慢 SQL 偶发执行、锁冲突 |
缓存 | 缓存穿透 / 缓存雪崩 / 失效重新加载 |
服务调用 | 被调用方突发阻塞(线程池临时满) |
🔍 排查建议:
- 链路追踪 + TraceID 分析异常链
- 查看 GC 日志,有无 Full GC 卡顿
- 缓存命中率分析,是否有瞬时失效
- 排查是否网络波动(跨区域、机房间、DNS)
- 数据库是否偶发锁冲突(如
innodb_status
查看锁等待)
🎯 对比小结
点 | 持续慢 | 偶发慢 |
---|
出现频率 | 一直都慢 | 偶尔慢一下 |
影响范围 | 所有请求或大量请求 | 少量请求 |
优先排查 | 代码/配置/系统资源 | 网络/GC/缓存 |
工具建议 | 监控系统 + Trace + Profile | Trace + GC 日志 + 慢 SQL |
⚙️ 建议监控维度(预防/定位都用得上)
- 请求耗时分布(99th vs avg)
- 线程池活跃线程数
- GC 次数和耗时
- 数据库慢查询日志
- 缓存命中率
- 系统负载、I/O、连接数
🔍 二、排查流程图(简洁版)
客户端慢 ↓
网络延迟? ↓ ↓ 是 ↓ → 网络问题(排查链路、DNS、跨机房等)
调用服务慢? ↓ ↓ 否 ↓
服务自身慢? ↓ → 服务代码逻辑问题 / 数据库慢 / 死锁
🔧 三、具体排查步骤
1. 🛠 客户端侧排查
- 是否只有某个服务变慢?
- 有无超时、重试等机制?是否在疯狂重试造成雪崩?
- 打印接口响应时间 + traceId,看哪个慢
- 是否限流、熔断器(Hystrix/Sentinel)触发了?
2. 📡 网络层排查(网关 / DNS / 服务注册)
- 查看请求链路是否跨机房、网络抖动
- 使用
ping
, traceroute
, curl -w
查看请求耗时 - 是否是负载均衡(如 Nginx、Ribbon)选错了节点?
- 服务发现(如 Nacos、Consul)注册信息是否正确?
3. 🧱 服务提供方排查
- 是否线程池打满了?(如 Tomcat、Dubbo 的工作线程)
- 内部依赖是否卡住了?(比如调用第三方接口或数据库)
- 服务日志中是否有慢接口的 traceId?
- 是否 GC 频繁?内存是否爆了?
可以重点看以下指标:
- CPU 使用率
- JVM GC 日志
- 线程堆栈(用
jstack
抓线程) - 服务端访问数据库或其他 RPC 的延时
4. 🧮 数据库或缓存排查
- SQL 是否变慢(慢 SQL 日志)
- 索引是否失效?
- 缓存是否击穿 / 失效?
- 数据量是否激增?(例如突然查大表)
5. 🔎 用链路追踪系统看整条链
如果你用了链路追踪系统(如 SkyWalking、Zipkin、Jaeger),可以:
✅ 找到调用路径
✅ 定位具体慢在哪一跳
✅ 查看是否有重试、异常、熔断、降级等日志
🧊 Bonus:预防机制建议
场景 | 建议做法 |
---|
服务慢 | 加限流 + 熔断 + 降级机制 |
DB 慢 | 加缓存、SQL 优化 |
网络抖动 | 使用服务探活 + 多节点容灾 |
异常调用链 | 上链路追踪工具 |