比较 gRPC 服务和 HTTP APICompare gRPC services with HTTP APIs

本文内容

作者:James Newton-King

本文介绍如何将 gRPC 服务与 HTTP API(包括 ASP.NET Core Web API)进行比较。用于为应用提供 API 的技术是一个重要选择,与 HTTP API 相比,gRPC 提供独特优势。本文讨论 gRPC 的优点和缺点,并提供优先于其他技术选择使用 gRPC 的建议方案。

概括比较High-level comparison

下表对 gRPC 和具有 JSON 的 HTTP API 之间的功能进行了简单比较。

功能gRPC具有 JSON 的 HTTP API
协定必需 ( .proto)可选 (OpenAPI)
协议HTTP/2HTTP
PayloadProtobuf(小型,二进制)JSON(大型,人工可读取)
规定性严格规范宽松。任何 HTTP 均有效。
流式处理客户端、服务器,双向客户端、服务器
浏览器支持无(需要 grpc-web)
安全性传输 (TLS)传输 (TLS)
客户端代码生成OpenAPI + 第三方工具

gRPC 优点gRPC strengths

性能Performance

gRPC 消息使用 Protobuf(一种高效的二进制消息格式)进行序列化。Protobuf 在服务器和客户端上可以非常快速地序列化。Protobuf 序列化产生的有效负载较小,这在移动应用等带宽有限的方案中很重要。

gRPC 专为 HTTP/2(HTTP 的主要版本)而设计,与 HTTP 1.x 相比,HTTP/2 具有巨大性能优势:

  • 二进制组帧和压缩。HTTP/2 协议在发送和接收方面均紧凑且高效。
  • 在单个 TCP 连接上多路复用多个 HTTP/2 调用。多路复用可消除队头阻塞

代码生成Code generation

所有 gRPC 框架都为代码生成提供一流支持。.proto 文件是 gRPC 开发的核心文件,它定义 gRPC 服务和消息的协定。通过此文件,gRPC 框架编码生成服务基类、消息和完整的客户端。

通过在服务器和客户端之间共享 .proto 文件,可以端到端生成消息和客户端代码。客户端的代码生成消除了客户端和服务器上的消息重复,并为你创建强类型客户端。无需编写客户端可在具有许多服务的应用程序中节省大量开发时间。

严格规范Strict specification

具有 JSON 的 HTTP API 没有正式规范。开发人员为 URL、HTTP 谓词和响应代码的最佳格式争论不休。

gRPC 规范对 gRPC 服务必须遵循的格式进行了规定。gRPC 消除了争论并为开发人员节省了时间,因为 gRPC 在各个平台和实现中都是一致的。

流式处理Streaming

HTTP/2 为长期实时通信流提供基础。gRPC 为通过 HTTP/2 进行流式传输提供一流支持。

gRPC 服务支持所有流式传输组合:

  • 一元(无流式传输)
  • 服务器到客户端流式传输
  • 客户端到服务器流式传输
  • 双向流式传输

截止时间/超时和取消Deadline/timeouts and cancellation

gRPC 允许客户端指定其愿意等待 RPC 完成的时间期限。截止时间会发送到服务器,如果超过截止时间,服务器可以决定要执行的操作。例如,服务器可能会在超时后取消正在进行的 gRPC/HTTP/数据库请求。

通过 gRPC 子调用传播截止时间和取消有助于强制执行资源使用限制。

gRPC 建议方案gRPC recommended scenarios

gRPC 非常适合以下方案:

  • 微服务 – gRPC 设计用于低延迟和高吞吐量通信。gRPC 对于效率至关重要的轻量级微服务非常有用。
  • 点对点实时通信 – gRPC 对双向流式传输提供出色的支持。gRPC 服务可以实时推送消息而无需轮询。
  • 多语言环境 – gRPC 工具支持所有常用的开发语言,因此,gRPC 是多语言环境的理想选择。
  • 网络受限环境 – gRPC 消息使用 Protobuf(一种轻量级消息格式)进行序列化。gRPC 消息始终小于等效的 JSON 消息。

gRPC 弱点gRPC weaknesses

浏览器支持受限Limited browser support

当前无法通过浏览器直接调用 gRPC 服务。gRPC 大量使用 HTTP/2 功能,且没有浏览器在 Web 请求中提供支持 gRPC 客户端所需的控制级别。例如,浏览器不允许调用方要求使用 HTTP/2,也不提供对 HTTP/2 基础框架的访问。

gRPC-Web 是 gRPC 团队的另一项技术,可在浏览器中提供有限的 gRPC 支持。gRPC-Web 由两部分组成:支持所有现代浏览器的 JavaScript 客户端,以及服务器上的 gRPC-Web 代理。gRPC-Web 客户端调用代理,代理将根据 gRPC 请求转发到 gRPC 服务器。

gRPC-Web 并不支持所有 gRPC 功能。不支持客户端和双向流式传输,并且对服务器流式传输的支持有限。

非人工可读取Not human readable

HTTP API 请求以文本形式发送,并且可进行人工读取和创建。

默认情况下,gRPC 消息使用 Protobuf 进行编码。尽管 Protobuf 可以高效地发送和接收,但其二进制格式非人工可读取。Protobuf 要求在 .proto 文件中指定消息接口描述来正确地反序列化。需要使用其他工具来分析网络上的 Protobuf 有效负载以及手动撰写请求。

服务器反射gRPC 命令行工具等功能可帮助使用二进制 Protobuf 消息。此外,Protobuf 消息支持与 JSON 之间的转换内置的 JSON 转换提供在调试时将 Protobuf 消息与人工可读取格式互相转换的高效方法。

备用框架方案Alternative framework scenarios

在以下方案中,建议使用其他框架取代 gRPC:

  • 浏览器可访问的 API – gRPC 在浏览器中未受到完全支持。gRPC-Web 可以提供浏览器支持,但它具有局限性并引入了服务器代理。
  • 广播实时通信 – gRPC 支持通过流式传输进行实时通信,但不存在将消息广播到注册连接的概念。例如,在聊天室方案中,应将新的聊天消息发送到聊天室中的所有客户端,这要求每个 gRPC 调用将新的聊天消息单独流式传输到客户端。SignalR 是适用于此方案的框架。 SignalR 具有持久性连接的概念,并内置对广播消息的支持。
  • 进程间通信 – 进程必须托管 HTTP/2 服务器才能接受传入的 gRPC 调用。对于 Windows,进程间通信管道是一种快速、轻便的通信方法。

其他资源Additional resources