RESTful与gRPC概述:背景与定义
聊到微服务架构,有个问题几乎绕不开:服务间到底怎么通信?
你想,拆成几十个甚至上百个服务之后,它们之间总要传递数据、调用接口。最主流的两个选择,就是RESTful和gRPC。我刚开始接触微服务时,也觉得这两个东西无非就是“一个用JSON,一个用二进制”。后来踩了几个坑才发现,背后的设计哲学差别挺大的。
这一章,我们先从背景和定义入手,搞清楚它们各自是什么、为什么会出现。
为什么我们需要对比它们?
先说背景。早期的单体应用里,所有模块都跑在一个进程里,方法之间直接调用,没有任何网络开销。后来业务复杂了,团队规模大了,单体变得越来越臃肿。大家开始把大应用拆成若干小服务,每个服务独立部署、独立开发。
问题就来了:服务A要调用服务B的数据,怎么办?
最简单的方案是HTTP + JSON,也就是RESTful的风格。但有些场景下,RESTful不够快,或者接口定义不够严谨。于是Google推出了gRPC,基于HTTP/2和Protocol Buffers,主打高性能、强类型。
核心矛盾:RESTful胜在简单、通用、生态成熟;gRPC胜在性能、效率、合约严格。选型不是非黑即白,得看场景。
RESTful:代表资源状态的表述性转移
RESTful的全称是Representational State Transfer,翻译过来挺拗口的——“表述性状态转移”。说白了,它是一种API设计风格,不是协议,也不是标准。
核心思想是什么呢?
- 一切皆资源(Resource)。比如用户、订单、商品,都是一个资源。
- 每个资源有唯一的URI标识。例如
/users/123表示ID为123的用户。 - 通过HTTP动词表达操作:GET获取、POST创建、PUT更新、DELETE删除。
- 无状态。每次请求都包含所有必要信息,服务端不保存客户端状态。
我记得第一次用RESTful写接口时,最直观的感受就是“清晰”。一个URL对应一个资源,GET就是查,POST就是增,一眼就能看出这个接口是干嘛的。团队协作时,沟通成本很低。
一个小技巧:设计RESTful接口时,URI里尽量用名词复数形式,比如 /orders,不要用动词。动词留给HTTP Method去表达。
gRPC:高性能的远程过程调用框架
gRPC呢?它来自Google,是一个高性能、开源的RPC(Remote Procedure Call)框架。和RESTful不同,gRPC不依赖HTTP动词,而是让你像调用本地方法一样调用远程服务。
gRPC默认使用Protocol Buffers(简称Protobuf)作为接口定义语言(IDL)和序列化工具。你写一个 .proto 文件,定义好服务接口和消息结构,然后通过protoc编译器生成客户端和服务端代码。
// 一个简单的proto示例
service UserService {
rpc GetUser (GetUserRequest) returns (User);
}
message GetUserRequest {
int32 user_id = 1;
}
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
为什么gRPC性能好?原因有几点:
- 基于HTTP/2,支持多路复用、头部压缩、服务器推送。
- Protobuf序列化后的数据体积比JSON小很多,解析速度也更快。
- 支持双向流、流式处理,适合实时通信场景。
我之前在做一个实时推荐系统时,用过gRPC做服务间调用。数据量一上来,JSON的解析开销就变得很明显。换成Protobuf之后,响应时间直接降了30%左右。嗯,这个差距在实际生产中是能感知到的。
注意一点:gRPC的调试和测试比RESTful要麻烦一些。你不能直接在浏览器里用curl或者Postman访问gRPC接口,需要专门的工具,比如grpcurl或BloomRPC。这是选型时容易被忽略的成本。
两者核心对比
下面这个表格,帮你快速抓住它们的本质差异:
| 维度 | RESTful | gRPC |
|---|---|---|
| 底层协议 | HTTP/1.1(也可用HTTP/2) | HTTP/2 |
| 数据格式 | JSON / XML / 文本 | Protocol Buffers(二进制) |
| 接口定义 | 无强制约束,靠文档约定 | 强类型,由proto文件定义 |
| 性能 | 中等,JSON解析有开销 | 高,序列化快、体积小 |
| 流式通信 | 需额外实现(如SSE) | 原生支持(双向流) |
| 浏览器支持 | 天然支持 | 需通过gRPC-Web转译 |
| 学习成本 | 低,大部分开发者都熟悉 | 中等,需学习Protobuf和工具链 |
看到这个表,你可能会想:“那是不是gRPC总是更好的选择?” 不一定。你想想看,如果你的上游是浏览器、移动端App,或者需要对接大量第三方系统,RESTful的通用性和易用性就特别重要。反之,如果是内部服务之间的高频调用、数据量大、对延迟敏感的场景,gRPC的优势就体现出来了。
知识体系总览
为了让你对本章内容有一个整体的印象,我画了一张结构图,把RESTful和gRPC的核心概念、定位以及选型的关键因素串起来。
从这张图可以看出,RESTful和gRPC并不是完全对立的关系。它们各自围绕不同的设计理念展开:RESTful强调资源与统一接口,gRPC强调合约与性能。选型时,需要综合考虑通用性、性能、团队技能、客户端类型等多个因素。
写在前面的话
好了,这就是第一章的内容。我不打算在一开始就告诉你“哪个更好”。因为在实际项目里,我见过有人用RESTful跑出了极好的性能,也见过有人用gRPC把自己折腾得够呛。工具本身没有的好坏,关键是你是否清楚每个工具最适合的战场。
接下来的章节,我们会深入协议细节、讲序列化效率、讲流式处理,还会拿出真实案例来分析选型成败。现在先把基础概念理清楚,后面就不容易跑偏。