gRPC 核心概念、架构和生命周期

未匹配的标注

gRPC 核心概念、架构和生命周期

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

不熟悉 gRPC?首先阅读 gRPC 简介。有关特定语言的详细信息,请参阅所选语言的快速入门、教程和参考文档。

概述

定义服务

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

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

gRPC 允许您定义四种服务方法:

  • 一元(Unary) RPC,客户端向服务器发送单个请求,并返回单个响应,就像普通函数调用一样。
rpc SayHello(HelloRequest) returns (HelloResponse);
  • 服务器流式(Server streaming) RPC,其中客户端向服务器发送请求并获取流以读回一系列消息。客户端读取返回的流,直到不再有 messages。gRPC 保证单个 RPC 调用中的消息排序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  • 客户端流式(Client streaming) RPC,其中客户端写入一系列消息并再次使用提供的流将其发送到服务器。一旦客户端完成了消息的编写,它将等待服务器读取消息并返回其响应。gRPC 再次保证单个 RPC 调用中的消息排序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  • 双向流式(Bidirectional streaming) RPC,其中双方使用读写流发送消息序列。这两个流独立运行,因此客户机和服务器可以按照他们喜欢的顺序进行读写:例如,服务器可以等待接收所有客户机消息,然后再写入响应,或者它可以交替地读消息,然后写消息,或者读写的其他组合。保留每个流中消息的顺序。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

您将在下面的 RPC 生命周期 部分中了解有关不同类型的RPC的更多信息。

使用API

.proto 文件中的 service definition 开始,gRPC 提供生成 client- and server-side 端代码的 protocol buffer 编译器插件。gRPC 用户通常在客户端调用这些 API,并在服务器端实现相应的 API。

  • 在 server 端,server 实现服务声明的方法,并运行 gRPC 服务器来处理 client 调用。gRPC 基础设施对传入请求进行解码,执行 service 方法,并对 service 响应进行编码。
  • 在 client 端,client 有一个称为 stub 本地对象(对于某些语言,首选术语是 client),它实现了与服务相同的方法。然后,client 可以在本地对象上调用这些方法,将调用的参数包装在适当的 protocol buffer 消息类型中-gRPC 负责将请求发送到 server 并返回 server’s protocol buffer 响应.

同步与异步

Synchronous RPC 调用在 server 响应到达之前阻塞,这与 RPC 所期望的过程调用的抽象最接近。另一方面,网络本身是 asynchronous 的,在许多情况下,能够在不阻塞当前线程的情况下启动 RPC 非常有用。

大多数语言中的gRPC编程API都有 synchronous 和 asynchronous 两种风格。您可以在每种语言的教程和参考文档中找到更多信息(完整的参考文档即将发布)。

RPC 生命周期

在本节中,您将更详细地了解 gRPC client 调用 gRPC server 方法时发生的情况。有关完整实现的详细信息,请参阅特定于语言的页面。

Unary RPC

首先考虑最简单的 RPC 类型,其中客户端发送单个请求并返回单个响应。

  1. 一旦 client 调用 stub 方法,server 就会收到通知,通知 RPC 已被调用,其中包含client 的 metadata 、方法名称和指定的 deadline(如果适用)。
  2. 然后,server 可以立即发送回自己的初始 metadata(必须在任何响应之前发送),或者等待 client 的请求消息。首先发生的是特定于应用的。
  3. 一旦 server 收到 client 的请求消息,它将执行创建和填充响应所需的任何工作。然后将响应(如果成功)连同状态详细信息(status code 和可选的状态 message)和可选的跟踪 metadata 一起返回给客户端。
  4. 如果响应状态为 OK,则 client 将获得响应,从而在 client 完成调用。

Server streaming RPC

server-streaming RPC 类似于 unary RPC,只是 server 返回一个响应 client 请求的消息流。发送所有消息后,server 的状态详细信息(status code 和可选状态 message)和可选的跟踪 metadata 将发送到 client。这就完成了 server 的处理。一旦 client 拥有 server 的所有消息,它就完成了。

Client streaming RPC

client-streaming RPC 类似于 unary RPC,除了 client 向服务器发送消息流而不是单个消息。server 用一条消息(连同状态详细信息和可选的尾部 metadata)进行响应,通常但不一定是在接收到所有 client 消息之后。

Bidirectional streaming RPC

在 bidirectional streamingRPC 中,调用由调用方法的 client 和接收 client metadata、方法名称和截止日期的 server 发起。server 可以选择发回其初始 metadata 或等待 client 开始流式传输消息。
client 和 server 流处理是特定于应用程序的。由于这两个流是独立的,client 和 server 可以按任何顺序读写消息。例如,server 可以等到收到 client 的所有消息后再编写消息,或者 server 和 client 可以玩“ping-pong”——server 收到请求,然后发送回响应,然后 client 根据响应发送另一个请求,以此类推。

Deadlines/Timeouts

gRPC 允许 client 指定他们愿意等待 RPC 完成多长时间,然后 RPC 以 DEADLINE_EXCEEDED 错误终止。在 server 可以查询特定 RPC 是否已超时,或者还有多少时间来完成 RPC。
指定截止日期或超时是特定于语言的:一些语言 API 根据超时(持续时间)工作

RPC termination

在 gRPC 中,client 和 server 对呼叫的成功做出独立的本地决定,并且它们的结论可能不匹配。这意味着,例如,您可以有一个在 server 成功完成的 RPC(“我已经发送了所有响应!”)但在 client 失败(“响应在我的截止日期之后到达!”)。server 也可以在 client 发送所有请求之前决定完成

Cancelling an RPC

client 或 server 可以随时取消 RPC。取消将立即终止 RPC,因此不再进行进一步的工作。

警告

取消前所做的更改不会回滚。

Metadata

Metadata 是关于特定 RPC 调用的信息(如 身份验证详细信息),以键-值对列表的形式,其中键是字符串,值通常是字符串,但可以是二进制数据。
密钥不区分大小写,由 ASCII 字母、数字和特殊字符 -, _, . 组成,并且不能以 grpc- 开头(这是为 grpc 本身保留的)。二进制值键以 -bin 结尾,而 ASCII 值键不以这个结尾。
Metadata 对 gRPC 本身是不透明的-它允许 client 向 server 提供与调用相关的信息,反之亦然。
Metadata 的访问取决于语言。

Channels

gRPC channel 提供与指定主机和端口上的 gRPC 服务器的连接。在创建 client stub 时使用。client 可以指定 channel 参数来修改 gRPC 的默认行为,例如打开或关闭消息压缩。通道有状态,包括 connectedidle
gRPC 如何关闭 channel 取决于语言。某些语言还允许查询 channel 状态。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~