go-grpc逻辑架构图

一、总体逻辑架构图(五层)

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 |

相关推荐
SEO_juper2 小时前
AI 爬虫 robots.txt 检查工具:你的站是不是把 AI 挡在门外了
开发语言·人工智能·爬虫·python·外贸独立站
木圭的AI时代指南2 小时前
实测 MiniMax M3.1 Flash:同一道 Three.js 大题,两个 agent 差出 4.6 倍
开发语言·javascript·ecmascript
星恒讯工业路由器2 小时前
工业路由器在中小 IoT 场景的选型与适配实践:从标准品到定制化的技术路径
开发语言·网络·物联网·php·工业路由器选型·工业网关odm·链路冗余切换
博.闻广见2 小时前
第10篇:Agent系统的性能优化 —— 缓存、压缩与动态模型路由
java·人工智能·后端·spring·agent
OKkankan2 小时前
python 进阶(三):面向对象进阶——从“会写 class”到设计可维护的后端对象
开发语言·数据结构·python
打工仔折腾 AI2 小时前
极空间部署Portainer实战:绕过Socket权限、解决9000端口冲突与固定内网访问
人工智能·后端·python·性能优化
魔都吴所谓2 小时前
【Python】 多线程 & 多进程&协程 常见题 + 应用场景整理
开发语言·python
FfHUCisI2 小时前
Linux 网络 IO 模型演进与 Epoll 内部机制
golang
king13598745502 小时前
LiteRT Tensor API:C++ 编写端侧模型图,XNNPACK、GPU 与 NPU 怎么选?
开发语言·c++·人工智能·chatgpt·架构·aigc