微服务可靠性三剑客:熔断、幂等与中间件编排理解及实战 后端可靠性设计熔断器、幂等性与中间件编排工作期间除了写业务代码也接触了几个微服务可靠性相关的设计模式。这部分是代码能跑和生产环境能抗之间的差距。一、熔断器问题微服务链路上下游挂了一个环节就逐级拖垮上游调用调用超时堆积线程/连接耗尽整条链路崩溃服务 A服务 B服务 C❌ 响应变慢雪崩熔断器就是让调用方在发现下游异常时主动拒绝、快速失败保护自己不被拖垮。熔断器是客户端中间件保护的是调用方不是下游。Google SRE 自适应算法Kratos 默认用的是 Google SRE 的自适应算法公式很简单requests K × successesrequests窗口内总请求数successes窗口内成功请求数K容忍系数默认 2当requests ≥ K × successes失败率太高开始按概率拒绝请求。比传统的连续失败 N 次就熔断好用的地方在于自适应不用设固定阈值拒绝概率随成功率平滑变化流量高时自动更敏感流量低时更宽容。三态模型SRE 条件触发requests ≥ K × successes冷却时间到默认 10s探测请求成功探测请求失败CLOSEDOPENHALF_OPENHALF_OPEN 是自动恢复的关键——冷却期后放少量请求试探下游恢复了就切回 CLOSED没恢复就回到 OPEN。整个过程不需要人工介入。Kratos 集成http.NewClient(http.WithMiddleware(circuitbreaker.Client()),)一行代码启用。和重试中间件配合时熔断器放重试前面——先判断熔没熔断再决定要不要重试。参数调优上支付类的高敏感业务把 Success 调高0.95日志类的低敏感业务调低0.7流量突增时降低 Request 阈值让熔断更敏感。二、幂等性设计问题网络不可靠客户端超时重试可能导致同一个请求被服务端执行多次。发奖、扣款这类写操作重复执行就是事故。幂等性同一个操作执行一次或多次结果相同。实现方案存在不存在请求携带幂等键查 Rediskey 存在?直接返回缓存结果获取分布式锁执行业务逻辑结果写入 Redis设 TTL 30min释放锁返回结果几个要点幂等键用 SHA256 对关键参数用户 ID 操作类型 唯一标识做哈希Redis 缓存执行结果TTL 覆盖重试窗口分布式锁防止并发下同一幂等键被同时执行适用场景不限于发奖——订单创建、支付回调、积分变更所有不允许重复的写操作都适用。三、中间件编排顺序Kratos 中间件链按声明顺序执行编排会直接影响行为grpc.WithMiddleware(recovery.Recovery(),// 1. 最内层panic 恢复logging.Client(),// 2. 日志circuitbreaker.Client(),// 3. 熔断器retry.Client(),// 4. 重试)先熔断再重试避免熔断期间还在做无效重试。recovery 在最内层保证任何 panic 都能兜住。四、总结这几个模式用同一个思路串起来假设一切都可能出问题。下游会挂就加熔断请求会重试就做幂等代码会 panic 就加 recovery网络会超时就设 deadline。学校里写的项目一般不关心这些也没有此类场景但生产环境里这些都是大概率事件。从写好一个功能到写出一个可靠的功能是最近最大的认知升级。