grpc适用于go微服务内部通信,http适用于对外暴露;协议选择取决于下游是否原生支持,而非单纯性能优劣。

gRPC 和 HTTP 在 Go 里不是“选哪个更好”,而是“谁干谁的活”
Go 微服务内部通信,grpc.Server 是默认首选;对外暴露给前端、App 或第三方系统,http.ServeMux(或 gin.Engine)必须上。这不是性能高低问题,而是协议契约是否被下游“原生理解”——浏览器不会解析 Protobuf 二进制流,Nginx 也看不懂 grpc-status header。
用错协议时最典型的错误现象
常见翻车现场:
-
rpc error: code = Unavailable desc = transport is closing:gRPC 客户端没配keepalive.EnforcementPolicy,内网连接空闲超时后突然断开,且无重连逻辑 - curl 调用返回乱码或 404:HTTP 服务用
http.Handle("/", handler)拦截全部路径,把 gRPC 的/helloworld.Greeter/SayHello请求吞掉了 - 前端调用失败 + 控制台报
ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY:直接在浏览器用 fetch 调 gRPC 接口——不行,得走grpc-web+ Envoy 代理 - 误用
net/rpc当 gRPC 替代:它不支持超时传播、拦截器、流式,gob编码只认 Go,2026 年已彻底不适合微服务间通信
性能差在哪?看三组关键数字
同一台机器、相同结构体、100 QPS 下实测对比:
- 序列化体积:
Protobuf约为JSON的 35%,网络传输字节少一半以上 - 反序列化耗时:
Protobuf解析速度约是JSON的 3 倍(Goencoding/json无缓存反射开销大) - 连接复用:
grpc.ClientConn默认复用单个 TCP 连接,100 并发 ≠ 100 个 socket;而http.Client若Transport.MaxIdleConnsPerHost配太小,会卡在连接池排队
结果就是:gRPC 平均延迟降 40%~60%,QPS 提升 3–5 倍——但这些优势只在服务间调用链路里生效。
立即学习“go语言免费学习笔记(深入)”;
别忽略调试和协作成本
上线前要问一句:谁来验证这个接口?
- 产品/测试同学要查数据?
curl -X POST http://localhost:8080/api/user?id=123一行搞定;grpcurl -plaintext localhost:9090 helloworld.Greeter/GetUser得先装工具、写 JSON body、处理 TLS 参数 - 需要 CDN 缓存用户资料?HTTP 的
Cache-Control、ETag是标准字段;gRPC 的metadata不被任何网关识别 - 日志链路要透传 traceID?HTTP 里加
X-Request-ID头就行;gRPC 必须用metadata.MD+ 拦截器手动注入,稍不注意就断掉
真正容易被忽略的,不是“该不该用 gRPC”,而是“有没有把它的长连接、流控、元数据透传、错误码映射这些细节,跟你的监控、日志、网关配置对齐”。漏掉一个,线上就多一个深夜告警。










