文章目录
- [对比 HTTP-REST 与 gRPC:各自的优缺点以及适用的场景](#对比 HTTP-REST 与 gRPC:各自的优缺点以及适用的场景)
-
- [HTTP-REST 与 gRPC 的核心区别](#HTTP-REST 与 gRPC 的核心区别)
- [gRPC 的优缺点](#gRPC 的优缺点)
- [HTTP-REST 的优缺点](#HTTP-REST 的优缺点)
- 适用场景
- 模糊点
-
- [什么是 Protobuf?](#什么是 Protobuf?)
- [HTTP/2 会将 HTTP 消息拆分并封装为二进制帧,那还能过使用 HTTP/2 构建 RESTful 接口吗?](#HTTP/2 会将 HTTP 消息拆分并封装为二进制帧,那还能过使用 HTTP/2 构建 RESTful 接口吗?)
- [如果 HTTP/2 支持 RESTful 接口,那为什么还需要 gRPC 呢?](#如果 HTTP/2 支持 RESTful 接口,那为什么还需要 gRPC 呢?)
对比 HTTP-REST 与 gRPC:各自的优缺点以及适用的场景

最近在总结近期学习的一个使用 gRPC + Gin 写的 Golang 微服务项目,微服务的框架选用的是 gRPC,它是 RPC 的一种,可以让客户端像是在调用本地函数一样对远程服务器当中的函数进行调用。
通过对该项目进行学习,我个人感觉 gRPC 与 HTTP-REST 所做的工作非常的相似,即根据发起的请求,返回相应的结果,因此对二者的区别进行了详细的调研,通过本篇文章进行简要的总结。
HTTP-REST 与 gRPC 的核心区别
特性 | gRPC | HTTP |
---|---|---|
协议 | 基于 HTTP/2 通信 | 通常基于 HTTP/1.1,但也可以使用 HTTP/2 |
数据格式 | 默认使用 Protobuf 进行字节流的序列化与反序列化 | 通常使用 JSON/XML |
通信模式 | 支持单向、双向流式通信 | 仅支持请求-响应,无流式 |
性能 | 高(二进制编码 + HTTP/2 多路复用) | 较低(文本解析 + HTTP/1.1 的无多路复用) |
适用场景 | 微服务之间的通信、实时流式数据 | Web API(返回 RESTful API 的数据给前端)、浏览器兼容场景 |
gRPC 的优缺点
✅优点
- 高性能:Protobuf 序列化和反序列化的编码体积小,使用 HTTP/2 传输降低延迟;
- 流式支持:适合实时数据传输(聊天、日志流);
- 强类型接口:通过
.proto
文件明确定义服务和方法; - 跨语言支持:自动生成多客户端语言。
❌缺点
- 浏览器支持差:需要 gRPC-Web 代理;
- 调试复杂:二进制数据需要经过转换才能为人所阅读;
- 生态工具较少:与 HTTP-REST 相比,gRPC 的工具链尚不成熟。
HTTP-REST 的优缺点
✅优点
- 通用性强:所有语言和平台(甚至是 IoT)原生支持;
- 可读性好:使用 JSON/XML 格式进行数据传输,便于接口调试和日志记录;
- 浏览器友好:直接用于前端调用。
❌缺点
- 性能较低:基于纯文本进行传输的效率较低,对纯文本进行解析的成本也较高;
- 无流式支持:HTTP-REST 仅支持通过请求-响应模式请求资源,不支持流式传输;
- 弱类型约束:接口规范依赖于文档。
适用场景
gRPC(HTTP/2 + Protobuf)
更适用于微服务之间的通信以及流式数据传输。
HTTP-REST(HTTP/1.1 或 HTTP/2 + JSON)
- 浏览器直接调用 API:如果使用 gRPC 则还需要 gRPC-web 进行代理,但是如果此时使用 HTTP-REST 可以直接获得 JSON 格式的数据;
- 快速原型开发:JSON 很容易手动构造,而 protobuf 则需要编译
.proto
文件; - 兼容旧系统:遗留系统可能不支持 gRPC,但基本都支持 HTTP + JSON。
模糊点
根据以上内容的总结,我产生了一些模糊点,在此列举并深入研究一下。
什么是 Protobuf?
Protobuf(Protocol Buffers)可以被理解为一种高效的数据序列化与反序列化协议,它的核心作用是将结构化的数据(如对象或消息)转换为二进制格式(序列化),或将字节流当中的二进制数据转换为原始数据(反序列化)。
如果想要使用 gRPC 来建立微服务,那么所编写的 proto 文件很有可能包含 service 和 message 两部分,service 当中定义了具体的远程过程调用函数,而 message 定义了 RPC 函数的请求结构体和响应结构体。
✅ Protobuf 的优点
- 高性能:二进制编码体积小,网络传输与序列化和反序列化的时间开销随之降低;
- 强类型与模式化:通过 proto 文件定义数据结构,避免运行时错误;
- 跨语言支持:protobuf 官方支持多种语言,生成的代码接口一致。
❌ Protobuf 的缺点
- 需要预编译:必须先定义 proto 文件并编译生成相应语言的代码,灵活性低于 JSON;
- 可读性差:二进制数据不能直接阅读,如需调试需要借助工具;
- 不适合所有场景:比如浏览器直接处理 Protobuf 格式的数据非常复杂,对于 gRPC 而言还需要借助 gRPC-web 代理才能过读取,浏览器场景更适合直接使用 JSON 进行序列化与反序列化。
💡 Protobuf 的常见使用场景
- 微服务通信:gRPC 默认使用 Protobuf 通信,替代 REST + JSON;
- 高性能存储:如数据库缓存、日志存储;
- 跨语言数据交换:不同语言服务间传递结构化数据(当然这一点基于 JSON 也能做到)。
HTTP/2 会将 HTTP 消息拆分并封装为二进制帧,那还能过使用 HTTP/2 构建 RESTful 接口吗?
完全可以。因为 HTTP/2 只是 HTTP 协议的一个版本,它将 HTTP 消息(Header + Body)拆分为二进制帧只是为了优化传输效率(多路复用、头部压缩),但不改变 HTTP 的语义。
具体来说,应用层的原始数据(比如 JSON 或 XML,也可以是 Protobuf)不会被拆分为二进制帧,HTTP/2 将数据转为二进制的时机是在将应用层数据通过传输层发送之前。在传输层发送字节流之前,HTTP/2 会将 HTTP 消息(Header + Body)拆分并封装为二进制帧,从而管理多路复用和优先级,提升了传输以及序列化反序列化的效率。
如果 HTTP/2 支持 RESTful 接口,那为什么还需要 gRPC 呢?
虽然 HTTP/2 本身已经优化了传输效率,但是 gRPC 基于 HTTP/2 进行了进一步的优化,具体体现在使用 Protobuf 作为数据的编码形式,为 HTTP/2 引入了强类型约束,并且具有高性能和跨语言的特性。
此外,HTTP/2 + REST-JSON 仅支持请求-响应模式,无法实现持续的数据流。
而 gRPC 原生支持 4 种通信模式:
- Unary RPC(类似 REST,单一请求-响应);
- Server Streaming RPC(服务端推送流,比如实时日志);
- Client Streaming RPC(客户端上传流,如文件分块上传);
- Bidirectional Streaming RPC(双向流,如聊天应用)。