这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

What is gRPC?

​ 新手入门 gRPC?从以下页面开始

1 - gRPC 简介

gRPC 和协议缓冲区(protocol buffers)的简介。

Introduction to gRPC - gRPC 简介

原文:https://grpc.io/docs/what-is-grpc/introduction/

​ gRPC 和协议缓冲区(protocol buffers)的简介。

​ 本页面向您介绍了 gRPC 和协议缓冲区。gRPC 可以将协议缓冲区用作其接口定义语言(IDL)和基础消息交换格式。如果您对 gRPC 和/或协议缓冲区还不熟悉,请先阅读本文!如果您只想立即深入了解 gRPC 并进行实践,选择一种语言,并尝试其中的快速入门

概述

​ 在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务端应用程序的方法,就像调用本地对象一样,这使得您更容易创建分布式应用程序和服务。与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可远程调用的方法及其参数和返回类型。在服务端,服务端实现此接口并运行 gRPC 服务端来处理客户端调用。在客户端,客户端具有一个存根(stub)(在某些语言中仅称为客户端),它提供与服务端相同的方法。

Concept Diagram

​ gRPC 客户端和服务端可以在各种环境中运行和相互通信,从 Google 内部的服务器到您自己的笔记本电脑,并且可以使用 gRPC 支持的任何语言进行编写。因此,例如,您可以轻松地在 Java 中创建一个 gRPC 服务端,并使用 Go、Python 或 Ruby 编写客户端。此外,最新的 Google API 将具有 gRPC 版本的接口,让您可以轻松地将 Google 功能集成到您的应用程序中。

使用协议缓冲区

​ 默认情况下,gRPC 使用 协议缓冲区(Protocol Buffers),这是 Google 成熟的开源机制(Google’s mature open source mechanism),用于序列化结构化数据(尽管它也可以与其他数据格式如 JSON 一起使用)。下面是它的工作原理的简要介绍。如果您已经熟悉协议缓冲区,请随时跳到下一节。

​ 在使用协议缓冲区时的第一步是在一个 proto 文件 的文件中定义要序列化的数据的结构:这是一个带有 .proto 扩展名的普通文本文件。协议缓冲区数据被结构化为 消息(messages),其中每个消息是包含一系列名值对(称为 字段(fields))的小型逻辑记录的信息。下面是一个简单的例子:

1
2
3
4
5
message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

​ 一旦您指定了数据结构,您就可以使用协议缓冲区编译器 protoc 根据您的 proto 定义生成所需语言的数据访问类。这些类提供了对每个字段的简单访问器,如 name()set_name(),以及将整个结构序列化/解析为原始字节的方法。例如,如果您选择的语言是 C++,在上面的示例上运行编译器将生成一个名为 Person 的类。然后,您可以在应用程序中使用此类来填充(populate)、序列化(serialize)和检索(retrieve) Person 协议缓冲区消息。

​ 您可以在普通的 proto 文件中定义 gRPC 服务,其中 RPC 方法的参数和返回类型被指定为协议缓冲区消息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// The greeter service definition. - Greeter 服务定义。
service Greeter {
  // Sends a greeting 发送问候
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name. 包含用户 name 的请求消息。
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings 包含问候语的响应消息。
message HelloReply {
  string message = 1;
}

​ gRPC 使用带有特殊 gRPC 插件的 protoc 从您的 proto 文件生成代码:您将获得生成的 gRPC 客户端和服务端代码,以及用于填充(populating)、序列化(serializing)和检索(retrieving )消息类型的常规协议缓冲区代码。要了解有关协议缓冲区的更多信息,包括如何在所选语言中安装带有 gRPC 插件的 protoc,请参阅 协议缓冲区文档

协议缓冲区版本

​ 虽然协议缓冲区已经可供开源用户使用一段时间了,但本站的大多数示例使用协议缓冲区版本 3(proto3),它具有稍微简化的语法、一些有用的新功能,并支持更多语言。proto3 目前可在 Java、C++、Dart、Python、Objective-C、C#、轻量级运行时(Android Java)、Ruby 和 JavaScript 中使用,这些版本可以从 协议缓冲区 GitHub 仓库获取,还有一个来自 golang/protobuf 官方包 的 Go 语言生成器,同时还有更多语言正在开发中。您可以在每种语言的 proto3 语言指南参考文档 中了解更多信息。参考文档还包括 .proto 文件格式的 正式规范

​ 总的来说,尽管您可以使用 proto2(当前默认的协议缓冲区版本),但我们建议您在使用gRPC时使用proto3,因为它可以让您使用完整范围的 gRPC 支持的编程语言,同时避免 proto2 客户端与 proto3 服务端之间的兼容性问题。

2 - 核心概念

介绍关键的 gRPC 概念,概述 gRPC 的架构和 RPC 生命周期。

Core concepts, architecture and lifecycle 核心概念、架构和生命周期

原文:https://grpc.io/docs/what-is-grpc/core-concepts/

​ 介绍关键的 gRPC 概念,概述 gRPC 的架构和 RPC 生命周期。

​ 对 gRPC 不熟悉吗?那么请首先阅读gRPC简介。对于特定语言的详细信息,请参阅您选择的编程语言的快速入门、教程和参考文档。

概述

服务定义

​ 与许多 RPC 系统类似,gRPC的基本思想是定义一个服务,指定可以远程调用的方法以及它们的参数和返回类型。默认情况下,gRPC 使用协议缓冲区作为接口定义语言 (IDL),用于描述服务接口和有效负载消息的结构。如果需要,也可以使用其他替代方案。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

​ gRPC 允许您定义四种类型的服务方法:

  • 一元 RPCs(Unary RPCs):客户端向服务端发送单个请求并获取单个响应,就像普通函数调用一样。

    1
    
    rpc SayHello(HelloRequest) returns (HelloResponse);
    
  • 服务端流式 RPCs:客户端向服务端发送请求并获取一个流以读取一系列的消息。客户端从返回的流中读取消息,直到没有更多的消息为止。gRPC 保证在单个 RPC 调用中消息的顺序。

    1
    
    rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
    
  • 客户端流式 RPCs:客户端写入一系列消息并将它们发送到服务端,再次使用提供的流。客户端完成写入这些消息后,等待服务端读取它们并返回响应。同样,gRPC 保证在单个 RPC 调用中消息的顺序。

    1
    
    rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
    
  • 双向流式 RPCs:双方都使用读写流发送一系列的消息。两个流独立运行,因此客户端和服务端可以按任何顺序进行读写操作:例如,服务端可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取消息然后写入消息,或者进行其他读写组合。每个流中的消息顺序保持不变。

    1
    
    rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
    

​ 您将在下面的RPC 生命周期章节中了解更多关于不同类型的 RPC。

使用 API

​ 从 .proto 文件中的服务定义开始,gRPC 提供了协议缓冲区编译器插件,用于生成客户端和服务端代码。gRPC 用户们通常在客户端调用这些 API,并在服务端实现相应的 API。

  • 在服务端,服务端实现了服务声明的方法,并运行 gRPC 服务端来处理客户端调用。gRPC 基础设施(The gRPC infrastructure)会解码传入的请求,执行服务方法,并对服务响应进行编码。
  • 在客户端,客户端有一个称为 存根(stub)(对于某些语言,首选术语是 客户端(client))的本地对象,实现了与服务相同的方法。然后,客户端只需在本地对象上调用这些方法,方法会将调用的参数封装为适当的协议缓冲区消息类型,将请求发送到服务端,并返回服务端的协议缓冲区响应。

同步 vs. 异步

​ 同步的 RPC (Synchronous RPC)调用会阻塞,直到从服务端接收到响应,这是RPC所追求的过程调用抽象的最接近逼真的表现。另一方面,网络本质上是异步的,在许多场景中,能够在不阻塞当前线程的情况下启动 RPC 是非常有用的。

​ 大多数语言中的 gRPC 编程 API 都提供同步(synchronous )和异步(asynchronous )两种风格(flavors)。您可以在各编程语言的教程和参考文档中了解更多信息(完整的参考文档即将推出)。

RPC 生命周期

​ 在本节中,您将更详细地了解当 gRPC 客户端调用 gRPC 服务端方法时发生的情况。有关完整的实现细节,请参阅特定编程语言的页面。

一元 RPC

​ 首先考虑最简单类型的 RPC,即客户端发送一个请求并收到一个响应。

  1. 一旦客户端调用存根(stub )方法后,服务端就会收到有关此调用的客户端元数据(metadata)、方法名称以及指定的截止时间(deadline)(如果适用)的通知。
  2. 然后,服务端可以立即发送自己的初始元数据(initial metadata)(必须在任何响应之前发送),或者等待客户端的请求消息。哪个先发生取决于应用程序的特定实现。
  3. 一旦服务端收到客户端的请求消息,它会执行必要的工作来创建和填充响应。然后,将响应(如果成功)与状态详细信息(状态码和可选状态消息)以及可选的尾部元数据(optional trailing metadata)一起返回给客户端。
  4. 如果响应状态为 OK,则客户端接收到响应,这样在客户端上就完成了调用。

服务端流式 RPC

​ 服务端流式 RPC 类似于一元 RPC,不同之处在于服务端以流式方式返回一系列消息作为对客户端请求的响应。在发送完所有消息后,服务端将其状态详细信息(状态码和可选状态消息)以及可选的尾部元数据(optional trailing metadata)发送给客户端。这样就完成了在服务端的处理。客户端在接收到所有服务端的消息后完成。

客户端流式 RPC

​ 客户端流式 RPC 类似于一元 RPC,不同之处在于客户端向服务端发送一系列消息,而不是单个消息。服务端以单个消息作为响应(连同其状态详细信息和可选的尾部元数据(optional trailing metadata))进行响应,通常在接收到所有客户端的消息后响应,但不一定是这样。

双向流式 RPC

​ 在双向流式 RPC 中,调用由客户端发起方法调用,服务端接收客户端的元数据、方法名称和截止时间。服务端可以选择发送初始元数据,或者等待客户端开始流式传输消息。

​ 客户端和服务端流处理是特定于应用程序的。由于这两个流是独立的,因此客户端和服务端可以按任何顺序读取和写入消息。例如,服务端可以等待接收到所有客户端的消息后再写入其消息,或者服务端和客户端可以进行"乒乓(ping-pong)“式的交互 —— 服务端接收请求,然后发送响应,然后客户端根据这一次的响应发送另一个请求,依此类推。

截止时间/超时

​ gRPC 允许客户端指定在 RPC 完成之前愿意等待的时间长度,如果RPC在此时间内未完成,将以DEADLINE_EXCEEDED错误终止。在服务端,服务端可以查询特定 RPC 是否已超时,或者还剩多少时间来完成 该RPC。

​ 指定截止时间或超时是特定于编程语言的:某些编程语言的 API 使用超时 timeout(时间段(durations of time)),而某些编程语言的 API 使用截止时间 deadline (固定时间点(a fixed point in time)),并且可能有默认的截止时间,也可能没有。

RPC 终止

​ 在 gRPC 中,客户端和服务器对调用的成功进行独立且本地的判断,它们的结论可能不一致。这意味着,例如,你可能有一个在服务端成功完成的 RPC(“我已发送完所有响应!"),但在客户端失败(“响应在我的截止时间之后到达!")。服务端也可以在客户端发送完所有请求之前决定完成调用。

取消 RPC

​ 客户端或服务端可以随时取消 RPC。取消操作会立即终止 RPC,不再进行进一步的工作。

警告

​ 在取消操作之前所做的更改不会被回滚。

元数据

​ 元数据(metadata)是关于特定 RPC 调用的信息(例如 认证细节),以键值对的形式表示,其中键是字符串,值通常是字符串,但也可以是二进制数据。

​ 键是不区分大小写的,并由 ASCII 字母、数字和特殊字符 -_. 组成,且不能以 grpc- 开头(这是为 gRPC 保留的)。二进制值的键以 -bin 结尾,而 ASCII 值的键则不以-bin结尾。

​ gRPC 不使用用户定义的元数据(这些用户自定义的元数据允许客户端提供与调用相关的信息给服务端),反之亦然。

​ 访问元数据是与编程语言相关的。

通道

​ gRPC 通道提供与指定主机和端口上的 gRPC 服务端的连接。在创建客户端存根(stub)时使用它。客户端可以指定通道参数以修改 gRPC 的默认行为,例如打开或关闭消息压缩(message compression)。通道具有状态,包括 connectedidle

​ gRPC 如何处理关闭通道取决于编程语言。某些编程语言还允许查询通道状态。

3 - FAQ

FAQ - 常见问题

https://grpc.io/docs/what-is-grpc/faq/

​ 以下是一些常见问题。希望你能在这里找到答案 :-)

What is gRPC? 什么是 gRPC?

​ gRPC 是一个现代的、开源的远程过程调用 (RPC) 框架,可以运行在任何地方。它使客户端和服务端应用程序能够透明地进行通信,并且更容易构建连接的系统。

​ 阅读更详细的 动机和设计原则(Motivation & Design Principles) 文章,了解我们为什么创建gRPC的背景。

gRPC 是什么的缩写?

gRPC Remote Procedure Calls, of course!

为什么我要使用 gRPC?

​ 主要的使用场景包括:

  • 低延迟、高可扩展性的分布式系统。
  • 开发与云服务端通信的移动客户端。
  • 设计一个需要准确、高效和语言无关的新协议。
  • 分层设计以实现扩展,例如认证、负载均衡、日志记录和监控等。

谁在使用它以及为什么?

​ gRPC 是 云原生计算基金会(Cloud Native Computing Foundation) (CNCF) 的项目。

​ Google 长期以来一直在使用许多 gRPC 的底层技术和概念。当前的实现被应用于 Google 的多个云产品和 Google 外部 API。它还被 SquareNetflixCoreOSDockerCockroachDBCiscoJuniper Networks 等许多组织和个人所使用。

支持哪些编程语言?

​ 请参阅 官方支持的语言和平台(Officially supported languages and platforms)

如何开始使用 gRPC?

​ 你可以按照这里的说明安装 gRPC。或者前往 gRPC GitHub 组织页面,选择你感兴趣的运行时或语言,并按照 README 中的说明进行操作。

gRPC 使用哪种许可证?

​ 所有实现都使用 Apache 2.0 许可证

我如何做出贡献?

​ 非常欢迎 贡献者,代码库托管在 GitHub 上。我们期待社区的反馈、补充和错误报告。个人贡献者和公司贡献者都需要签署我们的贡献者许可协议 (CLA)。如果你有关于 gRPC 的项目想法,请阅读指南并提交到 这里。我们在 GitHub 上的 gRPC 生态系统 组织下有一个不断增长的项目列表。

文档在哪里?

​ 请查阅 grpc.io 上的文档

What is the road map?

​ gRPC 项目有一个 RFC 过程,通过该过程设计和批准新功能的实现。这些功能在 该代码库 中进行跟踪。

gRPC 的版本支持有多久?

​ gRPC 项目没有长期支持 (LTS) 版本。根据上述滚动发布模型,我们支持当前的最新版本和上一个版本。这里的支持意味着修复错误和安全问题。

gRPC 的版本控制策略是什么?

​ 请参阅 gRPC 的版本控制策略 此处

最新的 gRPC 版本是多少?

​ 最新的发布标签是 v1.55.0。

gRPC 的发布时间是什么时候?

​ gRPC 项目采用的模式是主分支的 tip 在任何时候都是稳定的。该项目(在各种运行时中)目标是以尽力而为的方式每隔 6 周发布一个checkpoint 版本。请参阅此处的发布计划 。

我如何报告 gRPC 中的安全漏洞?

​ 如果要报告 gRPC 中的安全漏洞,请按照此处的文档流程进行操作。

是否可以在浏览器中使用它?

gRPC-Web 项目已经正式可用。

我可以在 gRPC 中使用我喜欢的数据格式(JSON、Protobuf、Thrift、XML)吗?

​ 可以。gRPC 的设计目标是支持多种内容类型的可扩展性。初始版本包含对 Protobuf 的支持,并在不同程度上支持其他内容类型,如 FlatBuffers 和 Thrift,但这些支持可能具有不同的成熟度水平。

我可以在服务网格(service mesh)中使用 gRPC 吗?

​ 可以。gRPC 应用程序可以像其他应用程序一样部署在服务网格中。gRPC 还支持 xDS API,可以在服务网格中部署 gRPC 应用程序而无需使用 sidecar 代理。gRPC 支持的无代理服务网格功能可以在 这里 查看。

gRPC 如何在移动应用程序开发中发挥作用?

​ gRPC和Protobuf提供了一种精确定义服务并自动生成可靠的iOS、Android客户端库以及提供后端的服务端的简便方法。客户端可以利用高级的流式传输和连接功能,帮助节省带宽,通过较少的TCP连接实现更多功能,并节省CPU使用和电池寿命。

为什么 gRPC 比使用 HTTP/2 传输的二进制数据块更好?

​ 这主要是gRPC在通信中的作用。然而,gRPC也是一组库,在各个平台上提供高级功能,这些功能通常是常见的HTTP库所不具备的。此类功能的示例包括:

  • 与应用层流量控制的交互
  • 级联的调用取消
  • 负载均衡和故障转移

为什么 gRPC 比 REST 更好/更差?

​ gRPC 在很大程度上遵循 HTTP/2 上的 HTTP 语义,但我们明确允许全双工流式传输。我们与典型的 REST 约定有所不同,因为为了性能原因,我们在调用分派过程中使用静态路径,从路径、查询参数和有效载荷主体中解析调用参数会增加延迟和复杂性。我们还形成了一套错误集,我们认为这些错误集与API用例更直接相关,而不是HTTP状态码。

gRPC 的发音是怎样的?

​ Jee-Arr-Pee-See.