选rest还是grpc取决于调用方、通信层级和工具链投入意愿:对外服务(浏览器/app/第三方)必须用rest;微服务内部高频调用、流式通信、多语言契约一致时应选grpc;真实系统常混合使用,关键在厘清调用方、中间链路控制力及proto生命周期管理能力。

选 REST 还是 gRPC,不取决于“哪个更先进”,而取决于你的调用方是谁、通信发生在哪一层、以及你愿不愿意为性能多搭几层工具链。
什么时候必须用 REST(HTTP/JSON)
如果你的服务要被浏览器、iOS/Android App、第三方系统(比如支付网关、CRM)直接调用,REST 就不是“可选”,而是事实标准。
- 浏览器原生支持
fetch和XMLHttpRequest,但无法直接发起 gRPC 调用(除非加grpc-web代理,额外运维成本) - 移动端 SDK 对 JSON 解析稳定可靠;Protobuf 需要额外集成 runtime,iOS 上还要处理
.proto生成 ObjC/Swift 代码的构建流程 - 防火墙、CDN、Nginx 默认放行 HTTP/1.1 流量;gRPC 的 HTTP/2 流量可能被中间设备静默丢弃(尤其老版本负载均衡器)
-
curl、Postman、Swagger UI 直接可用;调试 gRPC 得装grpcurl或 BloomRPC,且需配套.proto文件才能解析响应
什么时候该切到 gRPC
微服务内部调用,尤其是高频、低延迟、字段多、结构深的场景,gRPC 的收益是实打实的。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 同一数据中心内,千 QPS 级别的用户中心 ↔ 订单服务调用,
protobuf序列化比 JSON 快 3–4 倍,网络传输体积小 60%+(实测 1KB JSON → 400B protobuf) - 需要服务端流式推送实时状态(如订单物流轨迹)、客户端流式上传大文件分片、或双向流做协作文档编辑,REST 只能靠轮询或 WebSocket 拼凑,gRPC 原生支持
- 多语言团队共用一套接口契约:
user.proto生成 Go/Java/Python 客户端,字段类型、必选/可选、默认值全部一致,避免 JSON 字段名大小写错位(user_idvsuserId) - 你愿意接受
protoc+protoc-gen-go构建步骤,并统一管理.proto版本(否则不同服务用不同版本生成代码,运行时 panic)
Go 里最容易踩的 gRPC 实操坑
不是语法不会写,而是几个关键点没设对,导致线上请求卡死或返回空数据。
- 客户端连接未复用:
grpc.Dial()每次都新建*grpc.ClientConn,会快速耗尽 fd,正确做法是全局单例复用,或按目标服务粒度池化 - 超时完全没设:
context.Background()直接传进client.GetUser(ctx, req),一旦后端 hang 住,调用方 goroutine 永久阻塞——必须用context.WithTimeout(ctx, 5*time.Second) -
.proto字段缺json_name注解:比如定义了int32 user_id = 1;,但没加option (google.api.field_behavior) = REQUIRED;或json_name: "user_id",gRPC-Web 或 grpc-gateway 转 JSON 时字段名变成userId,前端收不到 - 服务端没配拦截器就上线:缺少统一日志、认证、限流,出问题只能靠业务代码里硬加
log.Printf,建议从第一天就启用grpc.UnaryInterceptor和grpc.StreamInterceptor
别忽略的混合方案
真实系统里,REST 和 gRPC 往往共存,而不是二选一。
- 对外暴露用 REST(
/api/v1/users),内部通信走 gRPC(UserService.GetUser),通过grpc-gateway自动生成 REST 接口,省去重复实现 - 健康检查、指标采集这类基础设施接口,坚持用轻量 REST(
/health,/metrics),不值得为它们引入 protobuf 工具链 - 某些核心服务(如风控决策)同时提供 gRPC 和 REST 两种 endpoint,由调用方按能力选择,但后端逻辑复用同一套 handler
协议选型真正难的不是技术对比表,而是厘清谁在调用你、你能控制多少中间链路、以及团队是否准备好维护 proto 文件生命周期——这些细节,比吞吐量数字更能决定成败。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










