Kratos Middleware 链
This content is not available in your language yet.
Kratos middleware 的核心是一个极小的函数类型:Middleware func(Handler) Handler。复杂能力来自组合顺序、transport context 和 operation selector,而不是来自一个庞大的基类体系。
先给答案:Kratos middleware 的核心是一个极小的函数类型:Middleware func(Handl…
Section titled “先给答案:Kratos middleware 的核心是一个极小的函数类型:Middleware func(Handl…”Kratos middleware 的核心是一个极小的函数类型:Middleware func(Handler) Handler。复杂能力来自组合顺序、transport context 和 operation selector,而不是来自一个庞大的基类体系。 正文沿“Chain 顺序 -> Selector -> 为什么需要 operation”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。
主要失效边界集中在“chain 顺序写反、selector 编译 regex 失败、缺少 Transporter”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。
Chain 顺序
Section titled “Chain 顺序”Chain(A, B, C)(endpoint) | v A(B(C(endpoint))) |request -> A -> B -> C -> endpointresponse <- C <- B <- AChain 在 middleware/middleware.go:7-20 从尾到头包装 handler,因此调用顺序与参数书写顺序一致,返回路径反向展开。
Selector
Section titled “Selector”middleware/selector 支持 prefix、regex、exact path 和自定义 Match:selector.go:28-89。匹配时从 server/client context 取 Transporter,以 operation 判断::92-123。命中后才执行内部 chain,否则直接放行::125-134。
为什么需要 operation
Section titled “为什么需要 operation”HTTP path 和 gRPC full method 都可以映射为 operation,但它们的底层请求对象不同。Transporter 统一提供 Kind、Endpoint、Operation、request/reply header:transport/transport.go:36-58,让日志、鉴权和 tracing 不需要绑定协议。
替代方案:每种协议各自实现一套 middleware API。 问题:日志、恢复、限流等基础能力重复实现,顺序也容易漂移。 设计:业务 middleware 只依赖通用 handler 和 context,协议层负责把它接到 interceptor 或 HTTP handler。
| 场景 | 风险 | 处理 |
|---|---|---|
| chain 顺序写反 | 鉴权或恢复失效 | 明确外层到内层的调用顺序 |
| selector 编译 regex 失败 | 规则被静默忽略 | 启动期校验配置和测试覆盖 |
| 缺少 Transporter | selector 不匹配 | 确保协议适配层先注入 context |
| middleware 修改 request | 并发数据竞争 | 只通过 context 传递请求级状态 |
函数式 middleware 的价值在于可组合和可测试;路由条件应独立于业务逻辑,形成可复用的选择器。
面试锚点
Chain为什么从后往前遍历?- selector 如何同时支持 HTTP 和 gRPC?
- middleware 与 transport context 的边界在哪里?