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 调用返回的错误。状态码命名空间应受到约束,以使这些错误处理决策更清晰。如果需要更丰富的领域特定状态,可以使用元数据交换机制来提供。