下面如下技术栈做示例:
Nacos + Gateway + OpenFeign + LoadBalancer + Seata + Sentinel + Micrometer + Prometheus + Grafana
整体原则:
先看现象定位层级,再看日志 + 指标;
最后链路追踪;
优先区分是网关、调用、限流熔断、分布式事务、注册配置中心问题
一、收集现象,先缩小范围(最重要,别直接翻日志)
先看几个问题,快速判断故障域:
- 报错是谁返回的?
- 页面直接
503/504/429/401:大概率 Gateway / Sentinel - 业务异常码(自定义 code):业务服务内部
- Feign 报错:远程调用问题
- 事务回滚、数据不一致:Seata
- 页面直接
- 影响范围:
- 单个接口?全部接口?所有服务?
- 是部分实例报错还是所有实例?
- 偶发还是必现?压力高才出现还是空闲也报错?
- 请求链路:客户端 → Gateway → 服务 A →(Feign)→ 服务 B
快速区分模块报错特征:
组件 典型报错 含义 Gateway 503 Service Unavailable 找不到后端实例(Nacos 注册 / LoadBalancer) Gateway 504 Gateway Timeout 后端服务处理超时 Sentinel 429 Too Many Requests / Blocked by Sentinel 限流、熔断、降级触发 OpenFeign ReadTimeout / ConnectTimeout Feign 调用超时、连接失败 LoadBalancer No instance available 没有可用服务实例 Seata Global transaction rollback、branch register fail 分布式事务注册失败、二阶段回滚 Nacos Connection refused、subscribe fail 注册中心 / 配置中心连接异常
为什么
503/504/429/401:大概率 Gateway / Sentinel这些 HTTP 状态码,是网关 / Sentinel 在「请求到达后端业务服务之前」就直接返回给浏览器 / 前端的,请求根本没进到业务微服务。
而业务服务内部抛异常,一般会走 Feign 转发,返回自定义业务码或者 500。
下面逐个拆解
请求链路:
前端 → Gateway 网关 →(Sentinel 嵌入在 Gateway)→ 业务微服务
1)503 Service Unavailable → Gateway 返回
含义:网关拿到请求,准备转发后端,但找不到可用实例。
- 触发点:Gateway 内部的 LoadBalancer 去 Nacos 拉实例列表,结果
No instance available。- 关键点:请求还没转发到业务服务,业务服务根本没收到这个请求。
- 返回方:Spring Cloud Gateway 直接构造 503 响应返回前端。
业务服务日志里找不到这条请求的 access 日志,因为请求根本没到达它。
区分:业务服务自己抛出 503 非常少见,业务服务一般只会返回 500。所以看到 503 优先怀疑网关。2)504 Gateway Timeout → Gateway 返回
含义:网关成功把请求转发给后端实例,但是后端长时间不返回响应,网关等超时了。
- 触发点:Gateway 配置的全局 / 路由级超时时间到了,网关主动断开连接,返回 504。
- 重点:请求已经到达业务服务,业务还在跑逻辑,但网关等不及直接断连接返回 504。
- 响应构造者:依然是 Gateway,不是业务服务。
业务服务会有这条请求日志,但业务返回的结果已经无法回传给前端,网关直接返回 504。
所以看到 504,源头是后端慢,但状态码是网关吐出。
3)429 Too Many Requests → Sentinel 返回(集成在 Gateway)
含义:请求被限流 / 熔断拦截。 Gateway 集成 Sentinel 网关流控之后,Sentinel 在网关层做拦截。
- 请求到达 Gateway,Sentinel 的 filter 先执行,判断命中流控 / 热点参数 / 熔断规则,直接拒绝。
- 请求根本不会转发到后端业务微服务。
- 返回报文:
Blocked by Sentinel,状态码 429。业务服务完全看不到这条请求,业务日志无记录。 这就是为什么 429 几乎优先定位 Sentinel。
补充:业务服务内部也可以集成 Sentinel,业务层 Sentinel 限流也会抛 BlockException,返回 429。
但线上绝大多数 429 高并发拦截,都是网关层 Sentinel,优先排查 Gateway 的 Sentinel 规则。
4)401 Unauthorized → Gateway 鉴权过滤器返回
含义:未认证、token 缺失 /token 过期。 鉴权逻辑一般放在 Gateway 全局 filter(Spring Security / 自研鉴权 filter)。
- 请求到网关,先执行鉴权 filter,token 校验失败,直接返回 401。
- 请求不会转发到后端业务服务。
业务微服务收不到请求,业务日志没有这条记录。 当然业务服务内部也可以返回 401,但是统一鉴权架构下,401 基本在网关层拦截。
二、第二步:看监控 Prometheus + Grafana(优先,不用翻海量日志)
Micrometer 埋点会把 JVM、线程池、HTTP、Feign、Sentinel、Nacos 指标上报 Prometheus,Grafana 大盘查看。
重点看这些指标:
- 服务健康
up指标:实例是否在线,up=0代表实例掉线(Nacos 注册失败 / 进程挂了)- JVM:堆内存、GC 频率、FullGC(频繁 FGC 直接 OOM 风险)、线程数
- Gateway 指标
- gateway_requests_seconds_count:请求量、状态码分布(4xx/5xx 数量)
- gateway_requests_seconds_sum:接口耗时,看慢请求
- Sentinel 指标
- sentinel_flow_qps、sentinel_block_qps:被限流 / 熔断的 QPS,看是不是规则误触发
- Feign / HTTP Client 指标
- feign_requests_seconds:远程调用成功率、超时次数
- 业务指标
- 接口异常率、P95/P99 耗时
排查顺序:
先看大盘有没有突增异常码、突增延迟、FullGC、线程爆满。
如果指标已经看到大量
sentinel_block,直接锁定是 Sentinel 限流熔断,不用去业务日志大海捞针。
三、第三步:日志排查(按链路顺序,从外到内)
日志分级:
Gateway 访问日志 → Gateway 错误日志 → 上游服务 access 日志 → 业务 error 日志 → Feign 调用日志 → Seata 事务日志 → Nacos 客户端日志
1. Gateway 网关日志
重点搜关键词:
No instance available:LoadBalancer 从 Nacos 拿不到实例。 排查:Nacos 控制台看服务是否注册成功;实例健康状态;是否 namespace/group 不一致;实例权重 / 下线状态。timeout:504 超时,检查网关超时配置、后端服务是否卡死。Sentinel:网关流控规则触发。
2. OpenFeign + LoadBalancer 调用异常
常见日志关键词:
ReadTimeout、ConnectTimeout、No instance available 排查方向:
- Nacos:目标服务是否注册成功,实例是否健康
- LoadBalancer:SpringCloud 新版移除 Ribbon,用 SpringCloud LoadBalancer,看是否配置了负载均衡策略
- Feign 超时:区分连接超时 connectTimeout / 读取超时 readTimeout
- connectTimeout:网络不通、端口不对、服务没启动
- readTimeout:服务 B 执行慢,超过 Feign 读取超时时间
- 注意:Gateway 超时 和 Feign 超时是两套独立配置,取最小的那个,很容易踩坑!
3. Sentinel 限流熔断日志
日志关键词:
BlockException、flow control、circuit breaker
- BlockException:被 Sentinel 拦截(限流、熔断、热点参数、授权规则) 排查:
- Sentinel 控制台查看实时 QPS,看触发哪条规则
- 区分:是流量真的超标 ,还是规则阈值配太小
- 熔断:服务失败率过高触发熔断,短时间拒绝请求,等半开探测
4. Seata 分布式事务(数据不一致问题专属)
日志关键词:
GlobalBegin、BranchRegister、GlobalCommit、GlobalRollback、lock conflict、timeout Seata 排查重点:
- TC 服务是否正常运行,业务服务能否连通 Seata TC
- 检查
undo_log表是否存在,undolog 是否生成(AT 模式) - 分支事务注册失败:DB 问题、SQL 异常、网络、事务分组配置不对
- 全局事务超时,自动回滚
- 锁冲突:多个事务争抢同一行数据,锁等待 / 回滚
数据不一致:优先看
undo_log表记录,看二阶段有没有正常提交 / 删除 undolog。
5. Nacos 注册 / 配置异常
日志关键词:
Nacos connection、subscribe、register 排查 Nacos 控制台:
- 确认 namespace、group、服务名和代码完全一致(大小写敏感!高频坑)
- 实例健康检查是否失败
- Nacos 服务集群是否压力大,客户端断连重连
- 配置读取失败:dataId、group 写错
Namespace:
默认值:
public,通常是dev/test/prodGroup 分组:
通常是业务域分组:
ORDER_GROUP、PAY_GROUP、USER_GROUP
四、常见真实场景
场景 1:Gateway 504 网关超时(多层超时配置不一致,最常见)
业务背景
商品详情接口,Gateway 转发请求到商品服务,商品服务内部需要 Feign 调用库存服务查询库存,高峰期大促。 链路:客户端 → Gateway → 商品服务 (Product) → Feign → 库存服务 (Stock)
故障现象
用户访问商品详情偶尔 504 Gateway Timeout;Grafana 看到 P99 耗时飙升;部分请求成功,慢请求超时。
排查步骤
-
错误码 504,代表网关收到请求,转发后端,后端长时间没有返回响应。
-
先看 Grafana:Gateway 请求 P99 超过 3000ms;库存服务接口 P99 耗时 2.8s。
-
核对三层超时配置(重点!很多人只配一处)
- Gateway 全局 timeout:3s
- Product 服务 Feign 调用 Stock 的 readTimeout:5s
- 库存服务 Tomcat 超时:8s
最小的超时是 Gateway 的 3s。库存查询耗时 2.8s,加上业务其他耗时,超过 3s → Gateway 直接断开连接返回 504,但下游业务服务还在继续执行,容易引发重复扣库存隐患!
-
看商品服务日志:Feign 调用 stock 服务最终成功返回数据,但是网关已经断开连接。
-
验证:调大 Gateway 超时到 6s,504 消失。
根因
多层超时配置没有统一,网关超时小于下游 Feign 超时,网关先超时切断连接,下游还在跑。
解决方案
- 规范:超时遵循外层网关超时 > 业务服务 Feign 超时 > 底层 httpclient 超时 例:Gateway 6s,Feign readTimeout 4s,httpclient 3.5s。
- 业务优化:库存查询增加缓存,降低接口耗时,从根源减少慢请求。
- 增加保护:Feign 超时后抛出异常,业务做降级返回缓存数据,而不是一直等待。
风险提醒
网关提前断开连接,下游服务事务还在执行,会出现用户看到报错,但业务数据已经入库的脏数据问题。
场景 2:Sentinel 网关流控误触发,大量 429 Blocked by Sentinel
业务背景
营销活动,Gateway 接入 Sentinel,配置网关流控规则:QPS 阈值 1000。上线活动预热,流量慢慢上涨。
故障现象
用户访问所有接口返回 429,提示Blocked by Sentinel: Flow control;Grafana sentinel_block_qps指标瞬间飙升,实际 QPS 才 600,远低于 1000 阈值。
排查步骤
- 看到 429,直接锁定 Sentinel,打开 Sentinel 控制台。
- 查看流控规则:规则配置是单机 QPS 1000,但是 Gateway 部署了 2 个实例。 总集群 QPS=600,分摊每个实例只有 300,远小于 1000。为什么限流?
- 查看 Sentinel 控制台的实时监控,发现热点参数规则被误开启,针对请求头的 token 做热点参数限流,同一个用户短时间请求,命中热点参数规则,直接拦截。
- 核对日志:
BlockException,flow control by param,确认是热点参数限流,不是全局 QPS。
根因
配置规则的时候混淆了网关流控(route 维度)、热点参数限流;测试环境复制规则到生产,忘记删除热点参数规则,单用户高频访问直接被拦截,和整体 QPS 无关。
另外一个高频同类场景:熔断规则。下游订单服务报错率超过阈值,Sentinel 触发熔断,网关直接拒绝请求,返回 BlockException。
解决方案
- 应急:Sentinel 控制台临时删除 / 关闭热点参数规则,流量恢复。
- 规范:区分规则类型
- 网关 route 流控:控制整个接口集群流量;
- 热点参数:控制单个用户 / 单个商品 ID 高频访问;
- 熔断规则:下游失败率过高自动熔断。
- 生产规则变更灰度发布,不要直接复制测试环境规则上生产。
事后预防
Grafana 增加 sentinel_block_qps 告警,并且区分 block 类型(限流 / 熔断 / 热点),告警信息带上阻断原因。
场景 3:Seata AT 模式,业务提交成功,但是数据库数据不一致(分布式事务经典)
业务背景
下单场景:创建订单(order 服务) + 扣减库存(stock 服务),使用 Seata AT 模式。 链路:订单服务开启全局事务,Feign 调用库存扣减。
故障现象
用户下单成功,订单表新增一条订单,但是库存没有扣减;没有明显报错,日志没有全局回滚日志。
排查步骤
- 现象:局部成功,另一分支没生效,典型分布式事务问题。
- 第一步:查询 seata 的 TC 控制台,查看全局事务记录。发现全局事务状态是Commit,但是库存分支事务没有执行。
- 查看库存服务日志:搜索关键词
BranchRegister,库存分支事务没有注册成功。 - 核对配置: 订单服务事务分组:
order_tx_group库存服务事务分组:stock_tx_groupSeata 客户端的 tx-group 必须和 TC 配置对应,两个服务事务分组不一致! 订单服务注册分支到 order_tx_group,库存服务往 stock_tx_group 注册,不在同一个事务组,库存分支无法加入全局事务。 - 补充验证:undo_log 表,库存服务这一条记录没有生成 undo_log。证明分支事务根本没有加入全局事务。
另一个常见 Seata 场景:锁冲突。高并发下单,多个事务修改同一商品库存,行锁争抢,部分分支事务报 lock conflict,全局事务回滚,订单创建成功后又被回滚,用户下单失败。
根因
两个微服务 Seata 事务分组配置不一致,无法加入同一个全局事务,库存分支不受全局事务管理。订单本地事务正常提交,库存分支不参与全局事务。
解决方案
- 修改所有参与同一个分布式事务的服务,保持事务分组名称完全一致。
- 每个库提前建立 undo_log 表,环境初始化脚本纳入发布流程。
- 大并发扣库存场景,增加 Seata 锁冲突监控,Grafana 采集 seata 锁冲突指标。
- 业务层面做库存预扣减,减少长事务,缩短行锁持有时间。
预防
发布前做 Seata 事务分组校验,单元测试覆盖分布式事务场景;TC 监控全局事务提交 / 回滚数量告警。
场景 4:服务 FullGC 导致偶发超时,链路所有调用都不稳定(隐藏最深的故障)
业务背景
用户中心服务,其他多个服务 Feign 调用用户信息查询接口,低峰正常,白天业务高峰期间歇性报错。
故障现象
随机报错:Gateway 504、Feign ReadTimeout,没有固定规律,接口有时正常有时超时。查看业务日志,没有业务异常堆栈。
排查步骤
- 报错五花八门,多个上游调用用户服务都超时,优先看 Grafana JVM 指标。
- Grafana 发现用户服务周期性 FullGC,每次 FullGC 持续 2~3 秒。发生 FullGC 的时候,JVM 所有业务线程 STW(Stop The World),整个服务暂停,不处理任何请求。
- 当 STW 期间,Feign 请求进来,服务停止响应 → Feign ReadTimeout;网关转发请求,服务卡住 → 504。
- 查看堆 dump:发现大量未释放的大对象,接口每次查询返回超大用户列表,没有分页,大对象频繁创建,老年代迅速占满触发 FullGC。
根因
接口没有分页,一次性加载大量数据,频繁创建大对象,JVM 老年代快速填满,周期性 FullGC,STW 暂停服务,造成间歇性超时。
解决方案
- 止血:临时扩容实例,分摊压力;或者临时下线该接口。
- 业务改造:接口增加分页,不一次性返回全量数据。
- JVM 调优:调整堆大小,优化 GC 回收器,增加堆内存监控告警,FullGC 次数 > 0 触发告警。
综合:一套线上故障排查顺序(可以直接落地给团队)
- 收集业务现象:哪些用户、哪些接口、报错页面提示、是否必现、并发情况
- 看 Grafana 大盘,优先看这几个指标:
- up(实例存活)
- JVM:FullGC、堆内存、线程数
- Gateway:状态码分布、接口 P95/P99 耗时
- Sentinel:block_qps,看限流熔断数量
- Feign 调用成功率、超时次数
- 定位故障组件:网关 / Nacos/Feign/Sentinel/Seata/JVM
- 进入日志系统,检索对应关键词抓取堆栈
- 打开中间件控制台:Nacos 实例、Sentinel 规则、Seata TC 事务记录
- 确认根因,先做应急止血,再修复代码 / 配置
- 低流量环境复现,验证修复效果,观察监控
- 复盘,增加告警、优化文档