Kratos 框架默认熔断器为空实现,必须显式引入 aegis/circuitbreaker/sre 并用 sre.NewBreaker 配置,设置 ErrorRatio、MinRequests 和 Window 参数,按服务隔离绑定 circuitbreaker.Client,降级逻辑需业务侧实现,并手动暴露 Prometheus 指标监控。

Kratos 框架本身不内置熔断器,必须显式引入并配置 aegis/circuitbreaker 或 sre 熔断器,否则 circuitbreaker.Client 中间件不会生效。
用 sre.NewBreaker 替代默认熔断器
Kratos 的 circuitbreaker 中间件默认使用的是空实现(即不熔断),真正起作用的是 go-kratos/aegis/circuitbreaker/sre 提供的 SRE 算法熔断器。直接用默认中间件不配 breaker 实例,等于没开熔断。
- 必须显式创建
sre.NewBreaker实例,并传入circuitbreaker.WithCircuitBreaker选项 -
WithErrorRatio(0.5)表示错误率 ≥50% 触发熔断;设太低(如 0.1)容易误熔,太高(如 0.9)失去保护意义 -
WithMinRequests(100)是滑动窗口内最小采样数,低于该值不统计——设太小(如 10)对短时抖动敏感,设太大(如 1000)响应滞后 -
WithWindow(60 * time.Second)是统计周期,不是“熔断后等多久重试”,重试由半开状态自动触发
circuitbreaker.Client 必须绑定到具体 gRPC 连接
熔断是按下游服务隔离的,不能全局复用一个中间件实例。常见错误是把 circuitbreaker.Client(...) 放在全局 middleware 链里,结果所有服务共用同一熔断状态。
- 每个
grpc.Dial应单独配置自己的circuitbreaker.Client,比如discovery:///user.service和discovery:///order.service必须分设 - 不要在 HTTP Server 的 middleware 中混用 gRPC 熔断器;HTTP 场景建议用
sony/gobreaker单独管理 - 如果用了服务发现,确保
discovery://前缀正确,否则breaker初始化失败但无报错,静默失效
降级逻辑必须写在业务调用侧,不在中间件里
Kratos 的 circuitbreaker 中间件只做状态判断和拦截,不提供 fallback 执行能力。所谓“降级”,得靠你自己在 client 调用处加 if err != nil 分支处理。
- 不要指望中间件自动返回兜底数据;它只会把
ErrOpenState或原始 error 向上传递 - 推荐模式:在 service 层封装 RPC 调用,
defer或if判断 err 后立即返回缓存值、静态默认值或预加载 fallback 数据 - 避免在 fallback 里再调一次 DB 或另一个微服务——这会让降级变成新故障点
- 配合
context.WithTimeout使用,防止主调用卡住导致整个请求超时,熔断器不管这个
必须暴露指标并观测 circuit_breaker_state
没监控的熔断器等于盲操作。Kratos + aegis 不会自动注册 Prometheus 指标,要手动调用 breaker.Metrics() 并注入 prometheus.Register。
- 重点盯三个指标:
circuit_breaker_state{service="user"}(当前状态)、circuit_breaker_requests_total{state="open"}(熔断请求数)、circuit_breaker_failures_total(失败计数) - 如果
circuit_breaker_state长期为closed,大概率是MinRequests没达标,或错误没被识别为 failure(比如 HTTP 5xx 没转 error) - 别依赖日志判断熔断是否生效——日志可能被过滤或丢失,指标才是唯一可信依据
最容易被忽略的是:Kratos 的熔断器只管“是否允许发起调用”,不管“调用花了多久”;超时控制、fallback 执行、错误归因全得你补全。它是个开关,不是保险箱。











