Service Mesh 超时重试:救服务,也可能放大故障
Service Mesh 超时重试:救服务,也可能放大故障
一、重试不是免费的稳定性
Service Mesh 让超时、重试、熔断、限流变成配置项,看起来很优雅。但重试不是免费的稳定性。一次请求失败后自动重试,短期可能救回偶发错误;如果下游已经过载,重试会把更多流量打过去,故障被放大。
很多线上事故不是没有重试,而是重试太激进。调用方、网格代理、SDK、业务代码都在重试,最终一个用户请求变成多次下游压力。稳定性配置如果不统一,救火工具会变成加压器。
二、超时和重试要一起设计
只配置重试不配置超时,很容易拖垮调用链。
flowchart TD A[上游请求] --> B[Mesh 代理] B --> C[调用下游] C --> D{是否超时或失败} D -->|是| E[按策略重试] E --> C D -->|否| F[返回结果] E --> G{达到重试上限} G -->|是| H[失败返回]整体超时时间要小于用户可接受时间。每次重试的超时、重试次数和退避策略,都要在总预算里。
三、策略要按接口类型区分
下面是一个简化配置思路。
retries: attempts: 2 perTryTimeout: 300ms retryOn: gateway-error,connect-failure,refused-stream timeout: 900ms读接口、幂等接口、短耗时接口更适合重试。写接口、支付接口、外部副作用接口必须非常谨慎。不能因为 Mesh 支持配置,就把所有接口套同一个模板。
四、重试要配合熔断和限流
如果下游已经过载,上游继续重试只会让队列更长。熔断可以快速失败,限流可以保护下游,重试则只处理短暂失败。三者要组合使用。
还要观察重试率。成功率稳定但重试率升高,是早期风险信号。用户还没感知失败,系统内部已经开始用额外成本维持表面稳定。这个阶段不处理,后面很可能直接雪崩。
重试预算也要跨层统一。业务 SDK 重试两次,Mesh 再重试两次,上游网关再重试一次,乘起来就很吓人。架构上要明确哪一层负责重试,其他层尽量只做超时和失败透传。
最后,灰度上线策略要小流量验证。超时重试配置影响面很大,一条规则可能改变整个服务拓扑的压力分布。先观察 P95、P99、错误率、重试率和下游 CPU,再逐步放大。
还要把超时预算从入口一路分配到下游。用户请求最多等 2 秒,网关、BFF、核心服务、数据库和外部接口就不能各自设置 2 秒。上游超时早于下游超时,才能避免无意义的后台工作继续消耗资源。
幂等键是重试的底线。写请求如果必须重试,就要让下游能识别重复请求,返回同一个结果或安全拒绝。没有幂等保护的重试,会把偶发网络抖动变成重复扣费、重复创建和重复通知。
可观测性也要跟上。每次重试都应该打上 attempt、upstream、原因和耗时标签。否则看到一次成功响应时,根本不知道背后已经重试了几轮。没有重试指标,团队会错过故障前奏。
最后,重试策略要有禁用开关。发现下游异常时,可以快速关闭某条路径的重试,只保留短超时和失败返回。没有开关,只能改配置发布,会拖慢止损速度。
还要把配置变更纳入审计。谁改了重试次数、超时时间、匹配路径和生效范围,都应该能查到。网格配置一旦出错,影响的不只是单个服务,而是整条调用链的压力分布。
故障演练也很必要。可以在测试环境模拟下游 500、慢响应、连接拒绝和部分超时,观察重试是否符合预期。没演练过的策略,上线后就是盲盒。
五、总结
Service Mesh 的超时和重试能提升稳定性,也可能放大故障。重试必须受总超时、接口幂等性、熔断限流和跨层预算约束。配置越简单,越要清楚它在故障时会制造多少额外流量。
