Skip to content

grpc-go Resolver 与 Balancer

This content is not available in your language yet.

resolver 把 target 变成地址、endpoint 和 service config;balancer 把这些控制面信息变成 SubConn 和 Picker;每次 RPC 只通过 Picker 选择可用 transport。三者分开后,地址来源和负载算法可以独立替换。

先给答案:resolver 把 target 变成地址、endpoint 和 service config;bala…

Section titled “先给答案:resolver 把 target 变成地址、endpoint 和 service config;bala…”

resolver 把 target 变成地址、endpoint 和 service config;balancer 把这些控制面信息变成 SubConn 和 Picker;每次 RPC 只通过 Picker 选择可用 transport。三者分开后,地址来源和负载算法可以独立替换。 正文沿“控制面到数据面 -> Balancer 与 Picker -> pickfirst 与 roundrobin”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。

主要失效边界集中在“resolver 发布空列表、Picker 内做网络调用、忽略 Done 回调”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。

target URI
-> resolver.Builder.Build
-> resolver.UpdateState
{Addresses, Endpoints, ServiceConfig}
-> ClientConn
-> balancer.UpdateClientConnState
-> create/update SubConn
-> UpdateState(connectivity, Picker)
-> pickerWrapper
-> RPC Pick

resolver 的注册表与核心接口位于 resolver/resolver.go:54-61、:232-329。ccResolverWrapper.start 构建 resolver,并用串行化回调隔离并发更新:resolver_wrapper.go:57-105;UpdateState 将地址和 service config 交回 ClientConn::127-179。

balancer 的 Builder、ClientConn、SubConn、Picker 和 Balancer 接口位于 balancer/balancer.go:139-365。balancer 管理连接集合并在状态变化时发布一个新的不可变 Picker;Picker 自身位于 RPC 热路径,只做快速选择并返回 PickResult.Done 供策略接收结果反馈。

pickerWrapper.pick 在 Picker 暂不可用时等待更新;fail-fast 调用遇到非临时选择错误直接返回,wait-for-ready 调用则继续等待 context:picker_wrapper.go:105-205。

pick_first 维护有序地址并选择首个 Ready SubConn:balancer/pickfirst/pickfirst.go:52-80、:210-330。round_robin 基于 endpoint 状态构建 ready picker:balancer/roundrobin/roundrobin.go:35-85。service config 决定使用哪种策略,而不是 resolver 直接选择节点。

替代方案:resolver 直接返回当前应访问的单个地址。

问题:地址发现、连接维护和负载算法耦合,无法维护多个 SubConn,也无法利用调用结果反馈。

设计:resolver 发布事实,balancer 管理候选连接,Picker 提供低成本数据面快照。

场景 风险 处理
resolver 发布空列表 Picker 进入无地址状态 区分真实删除与短暂发现失败
Picker 内做网络调用 每次 RPC 延迟抖动 控制面预计算,Pick 只做内存选择
忽略 Done 回调 自适应策略无结果反馈 正确传播完成状态
service config 错误 回退旧配置或默认策略 监控解析错误和当前策略

服务发现系统应把“发现了什么”“连接是否可用”“这次请求选谁”拆成三个阶段,分别优化一致性、状态收敛和热路径成本。

面试锚点

  • resolver、balancer、Picker 的职责分别是什么?
  • Picker 为什么适合做成状态快照?
  • wait-for-ready 在没有 Ready SubConn 时如何工作?