一、总体逻辑架构图(五层)
Go
┌────────────────────────────────────────────────────────────────────┐
│ 应用代码 / 生成的存根(.pb.go) │
│ server: pb.RegisterGreeterServer(s, &impl{}) │
│ client: c.SayHello(ctx, req) │
└───────┬───────────────────────────────────────────┬────────────────┘
│ │
════════▼═══════════════════════════════════════════▼════════════════
L1 门面层(根目录)
┌──────────────────────┐ ┌─────────────────────────────────┐
│ Server(server.go) │ │ ClientConn(clientconn.go:668) │
│ Serve/handleStream/ │ │ NewClient/Invoke/GetState/ │
│ processRPC(:1292) │ │ Connect/Close │
└──────────┬───────────┘ └───────┬─────────────────────────┘
│ 拦截器(interceptor.go,4种) │ call.go:Invoke + stream.go
│ stats/channelz 埋点 │ picker_wrapper.go(取货口)
════════════▼═════════════════════════════▼══════════════════════════
L2 策略层(可插拔注册表)
┌────────────────┐ ┌────────────────┐ ┌─────────────────────────┐
│ resolver/ │ │ balancer/ │ │ encoding/ + credentials/ │
│ dns/passthrough│ │ pickfirst/ │ │ proto(默认)/gzip/zstd │
│ manual/xds... │ │ roundrobin/ │ │ TLS/mTLS/ALTS/insecure │
│ resolver.go:54 │ │ ringhash... │ │ Register(名字→工厂) │
│ Register注册表 │ │ balancer.go:58 │ │ │
└───────┬────────┘ └───────┬────────┘ └─────────────────────────┘
│ resolver_wrapper.go │ balancer_wrapper.go
│ (门面↔策略的适配器,双向解耦)
═════════▼══════════════════════▼════════════════════════════════════
L3 传输层 internal/transport/(自研 HTTP/2,不用 net/http)
┌────────────────────────────────────────────────────────────────┐
│ ClientTransport(transport.go:714) ServerTransport(:756) │
│ http2_client.go:握手/reader/keepalive定时器/GOAWAY处理 │
│ http2_server.go:逐帧开流/流配额/MaxConnectionAge │
│ controlbuf.go:loopyWriter(:522) 每连接唯一写goroutine+优先级队列 │
│ flowcontrol.go + bdp_estimator.go:两级窗口+动态调优 │
└───────────────────────────────┬────────────────────────────────┘
│ x/net/http2 的 Framer + HPACK
═════════════════════════════════▼══════════════════════════════════
L4 字节层: HTTP/2 帧 over TCP(+TLS)
════════════════════════════════════════════════════════════════════
X 横切支撑(服务所有层)
metadata/status/codes(错误与带外数据) · keepalive(活性参数)
stats(观测) · channelz(运行时调试树) · grpclog(日志)
backoff(重连退避) · service_config.go(服务端下发的策略JSON)
E 生态扩展(独立子系统)
xds/(istio体系) · health/ · reflection/ · orca/(负反馈负载信息)
cmd/protoc-gen-go-grpc(代码生成) · examples/(40+特性样例)
三条铁律:依赖单向向下;L2 全是"注册表+接口"可插拔;L1 与 L2 之间靠 wrapper 适配(不直连)。
二、专题图 1:客户端一次一元调用(时序视角)
Go
业务 门面 策略层 传输层
│ SayHello │ │ │
├─────────────► Invoke(call.go:33) │ │
│ ├─ 拦截器链 ──────────┤ │
│ ├─ invoke ──► newClientStream │
│ │ ├──────► pick ◄─ Picker(v_n)
│ │ │ (picker_wrapper) │
│ │ │ │ SubConn.selected
│ │ │ ▼ │
│ │ └────────► NewStream ──► loopyWriter
│ │ │ HEADERS+DATA 帧
│ │ SendMsg: codec → 5B前缀 → 队列 ────────┤──► TCP
│ │ │◄── 响应帧
│ ◄────────────┴─ RecvMsg: Unmarshal + trailer状态 ◄────┤ reader goroutine
三、专题图 2:服务端 goroutine 分层(并发视角)
Go
Serve(server.go:906) [主] Accept循环,临时错误指数退避
└─ go handleRawConn [每连接×1] TLS+HTTP2握手 → 建 transport
└─ HandleStreams读循环 [每连接×1] 逐帧解析,新流回调
└─ go handleStream [每流×1 或 worker池]
└─ processRPC(:1292): 拦截链 → 业务handler → 回帧
+ loopyWriter [每连接×1] 唯一写出者
四、专题图 3:连接管理联动
Go
target:"dns:///svc" ──► Resolver(产地址+可选ServiceConfig)
│ UpdateState([A,B,C])
▼
Balancer(策略)──建──► SubConn ──Connect()──► newHTTP2Client(真实连接)
│ 收SubConn状态变化,产新版本Picker
▼
通道5态 = 所有SubConn状态的策略聚合
IDLE→CONNECTING→READY ⇄ TRANSIENT_FAILURE(退避重试) ; Close→SHUTDOWN
五、专题图 4:HTTP/2 报文解剖
Go
请求: HEADERS(:path=/包.服务/方法, content-type:application/grpc,
grpc-timeout) + DATA[1B压缩+4B长度+protobuf体]
响应: HEADERS(:status=200) + DATA[...] + trailer HEADERS(grpc-status)
多路复用: 每条RPC一个 StreamID,同一条TCP并发
流控: 连接级+流级两级窗口,WINDOW_UPDATE"还款",BDP动态放大
六、与 zap 的架构对照(同一学习路线的两站)
|-------|----------------------------------------------|-----------------------------------------------|
| 维度 | zap | grpc-go |
| 定位 | 单机日志库 | 网络RPC框架 |
| 核心抽象 | 4 小接口(Core/Encoder/WriteSyncer/LevelEnabler) | 4 组接口(ClientConn/Balancer/Resolver/Transport) |
| 扩展机制 | RegisterSink/RegisterEncoder(注册表) | resolver.Register/balancer.Register(同套路) |
| 性能哲学 | 池化+零分配 | 单写者+流控聚合,为吞吐不為零分配 |
| 并发模型 | 无后台goroutine(默认) | goroutine工厂:每连接/每流分层 |
| 门面与内核 | zap包 → zapcore | 根目录 → internal/transport |