RSS

gRPC 的动机与设计原则

动机

十多年来,Google 一直使用名为 Stubby 的单一通用 RPC 基础设施,用于连接在我们数据中心内部和跨数据中心运行的大量微服务。我们的内部系统早已采用了如今日益流行的微服务架构。拥有统一的跨平台 RPC 基础设施,使得能够推广到整个系统范围的改进,包括效率、安全性、可靠性和行为分析,这对于支持同期实现的惊人增长至关重要。

Stubby 具有许多出色的特性,但它不基于任何标准,并且与我们的内部基础设施耦合过于紧密,不适合公开发布。随着 SPDY、HTTP/2 和 QUIC 的出现,许多相同的特性已出现在公共标准中,同时还有 Stubby 不提供的其他特性。这使得我们清楚地意识到,是时候重构 Stubby,利用这些标准化成果,并将其适用范围扩展到移动、物联网和云用例。

原则与要求

服务而非对象,消息而非引用

推广微服务设计理念,即系统之间进行粗粒度消息交换,同时避免分布式对象的缺陷忽略网络的谬误

覆盖范围与简洁性

该技术栈应可在所有流行的开发平台上使用,并且用户可以轻松为其所选择的平台进行构建。它应可在 CPU 和内存受限的设备上可行。

免费与开源

使基本功能免费供所有人使用。将所有工件作为开源项目发布,采用应促进而非阻碍采用的许可。

互操作性与覆盖范围

线路上协议必须能够穿越常见的互联网基础设施。

通用性与高性能

该技术栈应适用于广泛的用例,同时与特定用例的技术栈相比,性能牺牲极少。

分层

技术栈的关键层面必须能够独立演进。线路上格式的修改不应干扰应用层的绑定。

载荷无关

不同的服务需要使用不同的消息类型和编码,例如 Protocol Buffers、JSON、XML 和 Thrift;协议和实现必须允许这样做。类似地,载荷压缩的需求因用例和载荷类型而异:协议应允许可插拔的压缩机制。

存储系统依赖流和流控制来表示大型数据集。其他服务,如语音转文本或股票行情接收器,则依赖流来表示时序相关的消息序列。

阻塞与非阻塞

支持客户端和服务器之间交换的消息序列的异步和同步处理。这对于在某些平台上进行伸缩和处理流至关重要。

取消与超时

操作可能开销很大且持续时间长——取消允许服务器在客户端行为良好时回收资源。当工作因果链被跟踪时,取消可以级联。客户端可以为调用指定超时,这使得服务能够根据客户端的需求调整其行为。

停止接收新请求

必须允许服务器通过拒绝新请求同时继续处理进行中的请求来优雅地关闭。

流控制

客户端和服务器之间的计算能力和网络容量通常不平衡。流控制可以更好地管理缓冲区,并提供针对过度活跃对端发起的 DOS 攻击的保护。

可插拔

线路上协议只是一个正常工作的 API 基础设施的一部分。大型分布式系统需要安全性、健康检查、负载均衡和故障转移、监控、跟踪、日志记录等等。实现应提供扩展点,允许插入这些特性,并在有用时提供默认实现。

扩展作为 API

需要服务之间协作的扩展应尽可能优先使用 API 而非协议扩展。这类扩展可能包括健康检查、服务内省、负载监控和负载均衡分配。

元数据交换

常见的跨领域关注点,如认证或跟踪,依赖于交换不属于服务声明接口的数据。部署依赖于它们以与服务暴露的单个 API 不同步的速度演进这些特性的能力。

标准化状态码

客户端通常以有限的方式响应 API 调用返回的错误。状态码命名空间应受到限制,以便更清晰地做出错误处理决策。如果需要更丰富的领域特定状态,可以使用元数据交换机制来提供。