追踪了 gRPC C++ 一次 RPC 的源码路径,才发现 Protobuf 到 TCP 之间藏着 6 个你没见过的中间层

张开发
2026/4/3 20:41:27 15 分钟阅读
追踪了 gRPC C++ 一次 RPC 的源码路径,才发现 Protobuf 到 TCP 之间藏着 6 个你没见过的中间层
用 gRPC 的人多,真正拆过 gRPC 线上报文的人少。大部分人对 gRPC 高性能的理解停留在两句话:“用了 Protobuf 所以序列化快”、“跑在 HTTP/2 上所以支持多路复用”。这两句都对,但加在一起也只说了个大概——就好像有人问你"汽车为什么能跑",你回答"因为有发动机和轮子"。没错,但发动机的气缸怎么点火、变速箱怎么传动、差速器怎么让两个轮子以不同速度转弯,全都被跳过了。问题在于:Protobuf 序列化出来的二进制数据,和 HTTP/2 的 DATA 帧之间,到底还隔着什么?你在 C++ 里调一下stub-SayHello(context, request, response),这个调用从 Protobuf 的SerializeToString()开始,到最终 TCP socket 上的write()结束,中间经过了多少层封装、多少次数据变换?很少有人完整地追踪过这条路径。答案是 6 层。不是 2 层,不是 3 层,是整整 6 层。每一层都有自己的帧头格式、自己的编码规则、自己的设计权衡和代价。这篇文章要做的事情就是:沿着 gRPC C++ Core 的源码路径(核心逻辑集中在src/core/ext/transport/chttp2/transport/目录),把这 6 层从里到外逐层拆开,看看每一层到底做了什么、为什么要这么做、付出了什么代价。先给出这 6 层的全景图,后面逐层拆解:应用层代码:stub-SayHello(request) │ ├─ 第 1 层:Protobuf 序列化 │

更多文章