文章目录
若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的动力!有问题请私信或联系邮箱:funian.gm@gmail.com
GRPC 和 HTTP(通常指 HTTP/1.1 及 RESTful 风格)的核心差异源于设计目标和底层实现:HTTP 是通用的应用层协议,而 GRPC 是基于 HTTP/2 的高性能 RPC 框架(本质是"协议+工具链"的组合)。

一、核心维度对比表
| 对比维度 | HTTP(RESTful 为主,基于 HTTP/1.1) | GRPC(基于 HTTP/2 + Protobuf) |
|---|---|---|
| 本质定位 | 通用应用层协议(无绑定框架) | 高性能 RPC 框架(协议+代码生成+工具链) |
| 传输协议依赖 | 支持 HTTP/1.1、HTTP/2、HTTP/3 | 强制依赖 HTTP/2 |
| 序列化方式 | 主流 JSON(文本格式),支持 XML/FormData | 强制 Protobuf(二进制格式) |
| 通信模式 | 以"请求-响应"为主(单向),支持 WebSocket 流式 | 支持 4 种模式:Unary(请求-响应)、服务端流式、客户端流式、双向流式 |
| 接口契约 | 松散约定(靠文档/Swagger 维护) | 强契约(通过 .proto 文件定义接口、参数、返回值) |
| 代码生成 | 无原生支持(需第三方工具如 OpenAPI Generator) | 原生支持跨语言代码生成(客户端/服务端 stub) |
| 性能表现 | 中等(JSON 解析慢、HTTP/1.1 队头阻塞) | 高性能(二进制序列化+HTTP/2 多路复用,低延迟、高吞吐量) |
| 跨语言支持 | 天然支持(基于 HTTP 协议),但接口一致性需手动保障 | 原生跨语言(.proto 文件统一约束,生成对应语言代码) |
| 可读性&调试 | 高(JSON 文本可直接阅读,curl/Postman 调试便捷) | 低(二进制数据需解码,需专用工具如 grpcurl) |
| 适用场景 | 对外 API(浏览器/第三方集成)、简单 CRUD、需可读性的场景 | 内部微服务通信、跨语言调用、实时流式传输(如聊天/监控)、高性能需求场景 |
二、关键差异拆解
1. 序列化:JSON vs Protobuf(性能核心差距)
- HTTP(JSON) :文本格式,人类可读,调试方便,但解析慢、数据体积大(比如一个对象的 JSON 表示比 Protobuf 大 30%-50%),不适合高并发场景。
- GRPC(Protobuf) :二进制格式,需通过
.proto文件定义数据结构(如message User { int32 id = 1; string name = 2; }),序列化/反序列化速度是 JSON 的 5-10 倍,数据体积小,带宽占用低。 - 核心优势:Protobuf 是"强类型"的,编译时会校验字段类型,避免 JSON 中"字段类型不匹配""缺字段"等运行时错误。
2. 传输协议:HTTP/1.1 vs HTTP/2(并发能力差距)
- HTTP/1.1 痛点 :
- 单连接下同一时间只能处理一个请求(队头阻塞),高并发需建立多个 TCP 连接,开销大;
- 头部信息重复传输(无压缩),浪费带宽。
- HTTP/2 赋能 GRPC :
- 多路复用:单 TCP 连接可同时处理多个请求/响应(通过帧标识归属),解决队头阻塞;
- 头部压缩(HPACK):减少重复头部的传输开销;
- 服务器推送:支持服务端主动向客户端推送数据(配合流式通信)。
- 注意:HTTP 也可基于 HTTP/2,但 GRPC 是"强制依赖",并充分利用了 HTTP/2 的流式能力。
3. 通信模式:单向请求 vs 多模式流式
- HTTP(REST):核心是"请求-响应"(比如 GET /user/1 → 返回用户数据),仅能通过 WebSocket 实现有限流式(需额外适配),不支持双向同时传输。
- GRPC :原生支持 4 种通信模式,覆盖更多场景:
- Unary:和 HTTP 一致(请求→响应);
- 服务端流式:客户端发 1 个请求,服务端返回多个连续响应(如实时日志推送);
- 客户端流式:客户端发多个连续请求,服务端统一返回响应(如批量上传文件);
- 双向流式:客户端和服务端同时双向传输(如即时聊天、视频通话信令)。
4. 接口契约:松散 vs 强约束(开发效率差距)
-
HTTP(REST):接口靠"约定"(比如 URL 路径、请求方法、参数格式),需通过文档(如 Swagger)同步给前端/客户端,容易出现"文档和实现不一致"(比如后端改了字段,文档没更)。
-
GRPC :接口通过
.proto文件"强定义",比如:protobufservice UserService { // Unary 接口 rpc GetUser(GetUserRequest) returns (GetUserResponse); // 服务端流式接口 rpc ListUsers(ListUsersRequest) returns (stream User); }编译后自动生成客户端(如 Java、Go、Python)和服务端代码,开发者无需手动写 HTTP 请求/响应逻辑,且接口变更会直接在编译时报错,避免"契约不一致"问题。
三、选型建议
| 场景 | 优先选 HTTP(REST) | 优先选 GRPC |
|---|---|---|
| 对外提供 API(浏览器/第三方调用) | ✅ (可读性强、调试方便、生态成熟) | ❌ (二进制不可读,第三方适配成本高) |
| 内部微服务通信 | ❌ (性能不足,契约易乱) | ✅ (高性能、强契约、跨语言友好) |
| 实时流式传输(日志/聊天/监控) | ❌ (需额外适配 WebSocket,功能有限) | ✅ (原生支持多模式流式,低延迟) |
| 跨语言调用(如 Go→Java→Python) | ❌ (需手动保障接口一致性) | ✅ (.proto 统一约束,自动生成代码) |
| 简单 CRUD 接口(如管理后台) | ✅ (开发快,curl/Postman 调试便捷) | ❌ (配置成本高,没必要) |
总结
- HTTP 是"通用协议",主打兼容性、可读性,适合对外场景;
- GRPC 是"高性能 RPC 框架",主打性能、强契约、流式通信,适合内部服务场景。
两者并非对立:很多系统会"对外用 HTTP REST,对内用 GRPC",兼顾易用性和性能。