跳转至

RPC vs REST vs GraphQL 深度技术选型

在现代分布式系统和微服务架构中,服务间通信方案的选择直接影响着系统的吞吐量、延迟、开发效率与演进成本。最常见的技术路线包括 gRPC (RPC)RESTful (HTTP/JSON) 以及 GraphQL


1. 核心特性多维对比

比较维度 gRPC RESTful (HTTP/1.1 or 2) GraphQL
基础协议 HTTP/2 (强制) HTTP/1.1 或 HTTP/2 通常基于 HTTP/1.1 或 HTTP/2
数据格式 Protocol Buffers (二进制) JSON / XML (纯文本) JSON (纯文本查询与响应)
接口契约 强制强契约 (.proto 文件) 松散/可选 (OpenAPI / Swagger) 强制强契约 (GraphQL Schema)
调用范式 面向动作与过程 (RPC) 面向资源与状态表述 (CRUD/URI) 面向声明式数据图查询 (Query)
通信模式 单向 (Unary)、客户端/服务端/双向流 通常单向请求-响应 (流需 SSE/WebSocket) 查询/变更 (单向)、订阅 (Subscription)
代码生成 官方工具链开箱即用 (protoc) 依赖第三方工具 (OpenAPI Generator) 依赖客户端工具 (Apollo, Relay)
传输效率 极高 (二进制压紧、头部压缩) 中等 (JSON 文本冗余、键名重复) 中等 (消除过度获取,但仍是 JSON)
浏览器亲和度 较弱 (需 grpc-web 代理转码) 极强 (原生支持、生态极其繁荣) (主流前端框架原生支持)
可读性与调试 需工具辅助 (grpcurl, grpcui) 浏览器原生支持、curl、Postman 友好交互界面 (GraphiQL)

2. 深度差异剖析

① 契约模型与序列化损耗

RESTful 中,通常使用 JSON 传输:

{
  "userId": 100234,
  "userName": "Alice Cooper",
  "email": "alice@example.com",
  "isActive": true
}
- 缺点:每次传输时字段键名(如 "userName")都会重复作为 ASCII 字符串出现;数值类型(如数字、布尔)需转换为文本,接收方必须重新做词法分析(Lexing)与语法解析(Parsing),消耗大量 CPU 时钟周期。

gRPC (Protobuf) 中: - 字段名在编译期被编码为序号(Field Number Tag),传输时只编码 (Tag << 3) | WireType(通常仅需 1 个字节)。 - 数值采用变长整型(Varint)直接按位操作,几乎无序列化/反序列化计算损耗。 - 实测在大数据量吞吐场景下,Protobuf 相比 JSON 能节省 50%~80% 的网络带宽,CPU 消耗降低 3~5 倍

② 网络连接复用与排头阻塞 (HOL Blocking)

sequenceDiagram
    autonumber
    rect rgb(240, 248, 255)
    Note over Client,Server: HTTP/1.1 (RESTful 常见模式)
    Client->>Server: TCP 握手 + TLS 协商 (RTT 耗时)
    Client->>Server: Request 1 (获取用户数据)
    Server-->>Client: Response 1
    Client->>Server: Request 2 (获取订单数据 - 必须等 R1 返回或建立新连接)
    Server-->>Client: Response 2
    end

    rect rgb(245, 255, 245)
    Note over Client,Server: HTTP/2 (gRPC 传输层)
    Client->>Server: 建立单个 TCP 长连接 (一次握手)
    par 多路复用 (Multiplexing)
        Client->>Server: Stream 1 (Header + Data)
        Client->>Server: Stream 3 (Header + Data)
        Server-->>Client: Stream 1 (Response)
        Server-->>Client: Stream 3 (Response)
    end
    end
  • HTTP/1.1 REST:即使开启 Keep-Alive,一个连接同一时刻也只能处理一个请求。并发请求要么在应用层发生排头阻塞,要么客户端必须建立多个 TCP 连接池(耗费大量文件描述符与内存)。
  • gRPC (HTTP/2):单条 TCP 连接上可并发数以千计的独立流(Stream),不同请求以二进制帧的形式交错传输,互不阻塞。

3. 架构选型决策矩阵

flowchart TD
    Start([通信场景选型]) --> Q1{调用发起方是哪类终端?}
    Q1 -- "浏览器 Web / 移动端公共网关 (North-South)" --> Q2{是否有极其复杂的动态字段聚合需求?}
    Q1 -- "集群内部微服务之间 (East-West)" --> A1[推荐选用 gRPC]

    Q2 -- "是 (如中台聚合、多变前端页面)" --> A2[推荐选用 GraphQL]
    Q2 -- "否 (标准通用业务接口)" --> A3[推荐选用 RESTful / HTTP+JSON]

    A1 -.-> Note1["若外部需调用 gRPC,可通过 gRPC-Gateway 暴露 REST"]

推荐选用 gRPC 的场景

  1. 微服务集群内通信(East-West Traffic):微服务之间的高频、低延迟 RPC 调用。
  2. 多语言混合架构:需要严格一致的强类型接口定义,由编译期保证类型安全。
  3. 流式传输需求:实时音视频信令控制、大文件分块上报、大数据日志清洗与分发。
  4. 资源受限环境:IoT 物联网设备、边缘计算节点(计算与带宽成本敏感)。

推荐选用 RESTful 的场景

  1. 公共开放 API(OpenAPI):面向第三方开发者或公众,生态兼容性优先级最高。
  2. 简单 CRUD 系统:无需复杂工具链,依靠浏览器和基础 HTTP 客户端即可轻松集成。

推荐选用 GraphQL 的场景

  1. BFF(Backend for Frontend)层:移动端和前端需求频繁多变,需要前端自主按需声明要获取的字段,杜绝 Over-fetching 与 Under-fetching。