本机实测同一个 Item 用 gRPC 和 HTTP/1.1 JSON:小消息线上字节是 gRPC 的 2.06 倍、64 KiB 是 1.33 倍;小消息延迟几乎没差、64 KiB 的 p50 慢 1.66 倍;64 并发下 HTTP/1.1 一条连接只有 16484 请求/秒,要 64 条连接才追平;新连接上 gRPC 更慢。
本机实测 gRPC 的连接池:MaxConcurrentStreams 为 100 时吞吐接近“连接数 × 100 ÷ 处理时间”直到 CPU 瓶颈;选在途最少的连接让吞吐高约 25% 但 p50 更差;本机上预热看不出收益;服务端每条空闲连接约 48 KiB、3 个 goroutine。
实测 gRPC 通道状态机:断开后是 IDLE 而不是 TRANSIENT_FAILURE;服务端回来后要等当前退避结束才 READY;握手超时按 MinConnectTimeout 进入 TRANSIENT_FAILURE;拒绝连接时一直 TRANSIENT_FAILURE;Close 后是 SHUTDOWN;多地址时 READY 表示至少一个子连接可用。
实测服务端 MaxConnectionAge:到期发 GOAWAY(最后流 2147483647,附加数据 max_age);±10% 抖动(2 秒设置下 1.87~2.21 秒);宽限默认无限时长流不受影响、宽限 1 秒时长流被打断;持续负载下换连接没有失败调用;与 MaxConnectionIdle 的区别。
实测服务 A 调服务 B 时的错误传播:原样透传会把 B 的 InvalidArgument、Unauthenticated 等错误当成客户端的错;message 会泄漏库表名和内网地址;两层各重试 3 次 B 收到 9 次;下游超时翻译成 Unavailable 还是 DeadlineExceeded 会改变重试行为。
实测 grpc-go 的日志与调试:默认连不上服务也没有任何输出,要 GRPC_GO_LOG_SEVERITY_LEVEL=warning 才看到连接失败;info 级别 42 条、verbosity=2 为 50 条;JSON 格式;grpclog.SetLoggerV2 接入自己的日志;channelz 里 RPC 层失败与流层成功的区别。