不熟悉 gRPC?首先阅读gRPC 简介。有关特定语言的详细信息,请参阅您选择的语言的快速入门、教程和参考文档。
与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以远程调用的方法及其参数和返回类型。默认情况下,gRPC 使用协议缓冲区作为接口定义语言 (IDL),用于描述服务接口和有效负载消息的结构。如果需要,可以使用其他替代方案。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
rpc SayHello(HelloRequest) returns (HelloResponse);
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
从.proto文件中的服务定义开始,gRPC 提供了生成客户端和服务器端代码的协议缓冲区编译器插件。gRPC 用户通常在客户端调用这些 API,并在服务器端实现相应的 API。
在本节中,您将仔细了解当 gRPC 客户端调用 gRPC 服务器方法时会发生什么。有关完整的实施细节,请参阅特定于语言的页面。
首先考虑最简单的 RPC 类型,其中客户端发送单个请求并返回单个响应。
服务器流式 RPC 类似于一元 RPC,除了服务器返回消息流以响应客户端的请求。发送所有消息后,服务器的状态详细信息(状态代码和可选状态消息)和可选尾随元数据将发送到客户端。这样就完成了服务器端的处理。客户端在拥有服务器的所有消息后完成。
客户端流式 RPC 类似于一元 RPC,不同之处在于客户端向服务器发送消息流而不是单个消息。服务器响应一条消息(连同其状态详细信息和可选的尾随元数据),通常但不一定在它收到所有客户端的消息之后。
在双向流式 RPC 中,调用由调用方法的客户端和接收客户端元数据、方法名称和截止日期的服务器发起。服务器可以选择发回其初始元数据或等待客户端开始流式传输消息。
客户端和服务器端流处理是特定于应用程序的。由于这两个流是独立的,客户端和服务器可以以任意顺序读写消息。例如,服务器可以等到它收到客户端的所有消息后再写入它的消息,或者服务器和客户端可以玩“乒乓”——服务器收到请求,然后发回响应,然后客户端发送基于响应的另一个请求,依此类推。
gRPC 允许客户端指定在 RPC 因错误而终止之前,他们愿意等待 RPC 完成多长时间DEADLINE_EXCEEDED。在服务器端,服务器可以查询特定的 RPC 是否已超时,或者还剩多少时间来完成 RPC。
指定期限或超时是特定于语言的:一些语言 API 根据超时(持续时间)工作,而一些语言 API 根据期限(固定时间点)工作,可能有也可能没有默认期限。
在 gRPC 中,客户端和服务器都对调用是否成功做出独立的本地判断,并且它们的结论可能不匹配。这意味着,例如,您可能有一个 RPC 在服务器端成功完成(“我已经发送了所有响应!”)但在客户端失败(“响应在我的截止日期之后到达!”)。服务器也可以在客户端发送所有请求之前决定完成。
客户端或服务器都可以随时取消 RPC。取消会立即终止 RPC,以便不再进行任何工作。
取消之前所做的更改不会回滚。
元数据
元数据是关于特定 RPC 调用的信息(例如身份验证详细信息),采用键值对列表的形式,其中键是字符串,值通常是字符串,但也可以是二进制数据。元数据对 gRPC 本身是不透明的——它允许客户端提供与服务器调用相关的信息,反之亦然。
对元数据的访问取决于语言。
gRPC 通道提供与指定主机和端口上的 gRPC 服务器的连接。它在创建客户端存根时使用。客户端可以指定通道参数来修改 gRPC 的默认行为,例如打开或关闭消息压缩。通道具有状态,包括connected和idle。
gRPC 如何处理关闭通道取决于语言。一些语言还允许查询通道状态。