主题
面试题蒸馏卡:微服务调用失败排查
问题:微服务之间为什么会调用失败?发生场景是什么?怎么排查?
一句话机制
微服务调用 = 网络 + 注册发现 + 服务实例 + 中间件(网关/熔断/限流) 串起来的链路;任一环抖动或配置不当,调用就失败。排查核心:先看错误类型定性 → 链路追踪定位环节 → 分层(网络/注册/配置/资源)逐层排除。
发生场景(为什么会失败)
- 网络层:分区、延迟、丢包、DNS 解析失败、防火墙/安全组
- 下游不可用:宕机、OOM、CPU 打满、发布中、容器被 kill(OOMKilled)
- 注册中心:没注册上、心跳过期被剔除、Nacos/ZK/Eureka 数据不一致 → 拿到错误/空节点
- 超时/重试不当:Feign/Ribbon 超时小于下游实际耗时;重试风暴放大下游压力
- 熔断/限流:下游熔断打开(Circuit Open)、网关/Sentinel 限流拒绝、触发降级
- 负载均衡:无可用节点、节点列表陈旧
- 版本/契约不兼容:字段缺失/类型变更,序列化反序列化失败(JSON/Protobuf)
- 资源耗尽:HTTP 连接池满、DB 连接池满、线程池满、文件句柄耗尽
- 认证/鉴权:token 过期、签名错、网关鉴权失败
- 数据问题:超大请求体、慢 SQL 拖垮下游
怎么排查
- 看错误类型定性
connection refused→ 下游没起/端口错/网络不通timeout→ 下游慢或超时配太小circuit open/flow limited→ 熔断/限流5xx→ 下游内部错;4xx→ 契约/鉴权
- 链路追踪:SkyWalking / Jaeger / Zipkin 看调用链哪一环慢或失败
- 下游健康:下游监控、日志、是否 OOM/CPU
- 注册中心:下游实例是否在线、IP 是否正确
- 网络:
ping/telnet/curl/mtr/tcpdump看丢包与链路 - 配置:超时、重试、熔断阈值、线程池/连接池大小
- 日志与控制台:下游 error 日志、网关 access log、Sentinel 控制台
怎么处理(体系化)
- 合理超时 + 重试(指数退避)+ 熔断降级
- 限流保护下游、防止雪崩(舱壁模式隔离资源)
- 注册中心健康检查 + 优雅上下线
- 监控告警 + 全链路追踪常态化
- 容量规划、按需扩容
- 契约测试保障版本兼容、灰度/回滚机制
追问链
- 超时和重试怎么配才合理? 超时设略大于下游 P99;重试加指数退避 + 上限,且只对幂等接口重试。
- 熔断和降级有什么区别? 熔断是"保护自己"(下游不健康就快速失败);降级是"兜底方案"(返回默认/缓存值)。
- 注册中心挂了会怎样? 取决于实现:Nacos/ZK 临时节点失效会剔除;客户端通常缓存旧列表,短期可用但无法感知新节点上下线。
- 怎么用链路追踪定位? TraceId 贯穿全链路,看哪一环
duration异常或status=ERROR。 - 雪崩怎么预防? 限流 + 熔断 + 舱壁隔离(线程池隔离)+ 超时,三件套防级联失败。
常见误解
- ❌ "调用失败就是下游挂了" —— 也可能是自己超时配太小、连接池满、DNS 解析失败。
- ❌ "重试一定能提高成功率" —— 重试风暴会压垮已不稳定的下游,雪上加霜。
- ❌ "加机器就能解决" —— 若是死循环/慢 SQL/代码 bug,扩容无效,先定位根因。