ClientConnInterface接口:
1.定义位置:
clientconn.go:645-651

2.具体作用:
只抽象"发起 RPC"的最小能力:一元调用(Invoke)+ 建流(NewStream).
3. 实现类:
ClientConn类(clientconn.go:668):


*acBalancerWrapper(balancer_wrapper.go:361,372):


balancer接口:
1.定义位置:
balancer/balancer.go:344

UpdateClientConnState:
最核心的入口。resolver 每次解析出新地址列表/服务配置,gRPC 就带着 ClientConnState{ResolverState, BalancerConfig} 调它。balancer 在这里 diff 新旧地址 → NewSubConn/Shutdown 多余的子连接。返回 ErrBadResolverState 会触发 gRPC 带指数退避地重试 ResolveNow(balancer.go:345-349),这是 balancer 反向影响 resolver 的唯一通道。
ResolverError:
解析失败的通知,balancer 通常把聚合状态置为 TransientFailure 并换上一个报错 Picker。
UpdateSubConnState:
某个子连接 CONNECTING/READY/TRANSIENT_FAILURE 时回调。已废弃------现在推荐建 SubConn 时通过 NewSubConnOptions.StateListener 注册回调(balancer.go:356-357),新策略都用 StateListener。
Close:
销毁前释放资源(未来会强制要求把所有 SubConn Shutdown)。
ExitIdle:
idle 模式被唤醒时,让策略主动发起重连(调 SubConn.Connect)。
2.具体作用:
接收 gRPC 的输入(地址、连接状态),管理 SubConn,聚合连接状态,生成并更新 Picker.
3. 实现类:
pickfirstBalancer(balancer/pickfirst/pickfirst.go:210):
默认策略。不用 base,面向单个SubConn顺序试连第一个可用地址
rrBalancer(balancer/roundrobin/roundrobin.go:66):
轮询,基于 base,自己只有 ~30 行Picker.
ringhashBalancer(balancer/ringhash/ringancer.go:181→ringhash.go:181):
一致性哈希环(xDS 用).
leastRequestBalancer(balancer/leastrequest/leastrequest.go:131):
最少请求数(借助 ORCA 负载上报).
wrrBalancer(balancer/weightedroundrobin/balancer.go:224):
加权轮询.
weightedTargetBalancer(balancer/weightedtarget/weightedtarget.go:100):
按权重分组再下发子策略.
lbBalancer(balancer/grpclb/grpclb.go:465):
老的 gRPC LB 协议(客户端连 LB server 拿地址).
rlsBalancer(balancer/grpclb/grpclb.go:465):
路由查找服务:按 key 查 RLSserver 决定路由到哪.
Resolver接口:
1.定义位置:
resolver/resolver.go:319-327

2.具体作用:
ResolveNow:
gRPC 主动要求重解析的提示通道。典型触发:balancer 发现地址全连不上、返回 ErrBadResolverState,ClientConn 就带指数退避地反复调它------它是 balancer → resolver 的反馈回路,让解析器知道"你给的结果不可用,刷新一下"。声明为"可忽略"是给 watch 型 resolver(xDS)留的余地:人家本来就是推送模式,没有"再查一次"的概念。
Close:
与 ClientConn 同生共死,释放 DNS goroutine、取消订阅、断开 xDS stream。
3. 实现类:
passthroughResolver(internal/resolver/passthrough/passthrough.go:49):
最"懒"的 resolver:Build 时把 target 原样当作地址 UpdateState(passthrough.go:55),ResolveNow 空实现(:58)。IP
直连场景用,老 Dial("localhost:50051") 背后就是它.
dnsResolver( internal/resolver/dns/dns_resolver.go:193):
真解析:A/AAAA 记录、SRV 记录(_grpclb._tcp)、TXT 里的服务配置;带结果缓存、退避重试。NewClient 无 scheme 时的默认.
delegatingResolver(internal/resolver/delegatingresolver/delegatingresolver.go:184):
新的组合壳:target 里的裸 IP 交给 passthrough、主机名交给 dns,并处理双栈 Endpoint 聚合------未来默认 resolver 的方向.
xdsResolver(internal/xds/resolver/xds_resolver.go:276):
从 xDS 管理面订阅 LDS/RDS,输出的是"该用哪个 LB 策略 + 集群配置",而非简单地址列表.
manual.Resolver(resolver/manual/manual.go:98):
测试专用:手动 UpdateState() 注入任意 State,grpc-go 自己的测试大量使用.
Transport 接口
1.定义位置:
internal/transport/transport.go,两个接口,分别管客户端和服务端:
ClientTransport ------ transport.go:714,7 个方法
Go
type ClientTransport interface {
// Close tears down this transport. Once it returns, the transport
// should not be accessed any more. The caller must make sure this
// is called only once.
Close(err error)
// GracefulClose starts to tear down the transport: the transport will stop
// accepting new RPCs and NewStream will return error. Once all streams are
// finished, the transport will close.
//
// It does not block.
GracefulClose()
// NewStream creates a Stream for an RPC.
NewStream(ctx context.Context, callHdr *CallHdr, handler stats.Handler) (*ClientStream, error)
// Error returns a channel that is closed when some I/O error
// happens. Typically the caller should have a goroutine to monitor
// this in order to take action (e.g., close the current transport
// and create a new one) in error case. It should not return nil
// once the transport is initiated.
Error() <-chan struct{}
// GoAway returns a channel that is closed when ClientTransport
// receives the draining signal from the server (e.g., GOAWAY frame in
// HTTP/2).
GoAway() <-chan struct{}
// GetGoAwayReason returns the reason why GoAway frame was received, along
// with a human readable string with debug info.
GetGoAwayReason() (GoAwayReason, string)
// Peer returns information about the peer associated with the Transport.
// The returned information includes authentication and network address details.
Peer() *peer.Peer
}
开流:NewStream 是数据面的真正入口------把 CallHdr(method、:authority、压缩、credentials,transport.go:670-710)变成一个 HTTP/2 stream。之前讲的 acBalancerWrapper.NewStream 最终就落到这。
关闭语义:暴力 Close vs 优雅 GracefulClose,后者对应连接排水的方向;
健康信号:Error()/GoAway() 两个 channel 是 transport → ClientConn 的反馈通道:addrConn 里有 goroutine 监听它们------Error 触发重连(退避),GoAway 触发重新解析 + 连接迁移(服务端要下线时提前通知,客户端去连新的后端,在途请求不受影响------这就是 gRPC 优雅重启的底层机制);
元信息:Peer() 给 stats/tracing 用。
ServerTransport ------ transport.go:756,4 个方法

HandleStreams:
读循环:每收到一个新流,回调给 Server 分发.
Close:
拆连接,在途流异步终止.
Drain:
给客户端发 GOAWAY:别再发新请求.
Peer:
对端信息快照.
2.具体作用:
3. 实现类:
现http2Client(internal/transport/http2_client.go(NewStream:778,Close:1028...):
唯一的客户端实现。自管 TCP/TLS 拨号、framer、读循环 + loopyWriter 写循环(专门的发帧 goroutine,攒批写),还负责
HTTP/2 SETTINGS MAX_CONCURRENT_STREAMS 限流(NewStream 时可能排队/失败)
http2Server(internal/transport/http2_server.go(HandleStreams:646,Drain:1394):
服务端主力:accept 后的 HTTP/2 连接.
serverHandlerTransport(internal/transport/handler_server.go:145):
备用服务端实现:不走自己的 HTTP/2,而是架在 Go 标准库 http.Server 的 Handler 上(h2c)。场景:gRPC 和普通 HTTP 共用
443 端口(如 cmux、ServeMux 一端口多协议).
客户端只有 http2Client 一个实现,却仍抽接口------为将来换传输实现(in-process、quic 等)留缝,也为了让 addrConn/csAttempt 依赖抽象而非具体类型。