核心概念、架构和生命周期
介绍 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 允许定义四种类型的服务方法:
-
单向 RPC(Unary RPC):客户端发送单个请求到服务器并收到单个响应,就像正常的函数调用。
rpc SayHello(HelloRequest) returns (HelloResponse);
-
服务器流式 RPC(Server streaming RPC):客户端发送请求到服务器并获得一个流,读取一系列的消息。客户端从返回的流中读取,直到没有更多消息为止。gRPC 保证在单个 RPC 调用中的消息顺序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
-
客户端流式 RPC(Client streaming RPC):客户端发送一系列消息到服务器,使用提供的流。在客户端完成消息发送后,等待服务器读取并返回响应。同样,gRPC 保证在单个 RPC 调用中的消息顺序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
-
双向流式 RPC(Bidirectional streaming RPC):双方都使用读写流发送一系列消息。两个流是独立的,客户端和服务器可以按任意顺序进行读取和写入。例如,服务器可以等待接收到所有客户端的消息后再写响应,也可以交替地读一个消息然后写一个响应,或以其他组合的方式进行读写。每个流中的消息顺序被保留。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
您将在下面的 RPC 生命周期 部分学习更多不同类型的 RPC。
RPC 生命周期
在本节中,您将深入了解当 gRPC 客户端调用 gRPC 服务器方法时发生的过程。有关完整的实现细节,请参阅特定语言的页面。
服务器流式 RPC
服务器流式 RPC 类似于单向 RPC,只不过服务器返回一个消息流来响应客户端的请求。在发送完所有消息后,服务器会发送状态详情(状态码和可选的状态消息)以及可选的尾部元数据给客户端。客户端在接收到所有服务器消息后完成。
客户端流式 RPC
客户端流式 RPC 类似于单向 RPC,只不过客户端发送一系列消息到服务器,而不是单个消息。服务器通常在接收到所有客户端的消息后,发送一个响应(包括状态详情和可选的尾部元数据),但不一定是这样。
双向流式 RPC
在双向流式 RPC 中,调用由客户端发起,服务器接收到客户端的元数据、方法名和截止时间。服务器可以选择立即返回初始元数据,或者等待客户端开始流式消息。
客户端和服务器的流处理是应用程序特定的。由于 两个流是独立的,客户端和服务器可以按照任意顺序读取和写入消息。例如,服务器可以等待接收到所有客户端的消息后再写入响应,或者客户端和服务器可以进行 “乒乓” 式的交互 —— 服务器接收到请求后,返回响应,客户端根据响应发送另一个请求,以此类推。
截止时间/超时
gRPC 允许客户端指定希望等待 RPC 完成的最长时间,如果超时,则 RPC 会终止并返回 DEADLINE_EXCEEDED 错误。服务器端可以查询某个 RPC 是否超时,或者距离 RPC 完成还有多少时间。
指定截止时间或超时是语言特定的:有些语言 API 以超时(时间段)的形式工作,而有些语言 API 以截止时间(固定时间点)形式工作,并且可能或可能没有默认的截止时间。
RPC 终止
在 gRPC 中,客户端和服务器独立且局部地确定调用是否成功,他们的结论可能不一致。这意味着,例如,一个 RPC 可以在服务器端成功完成(“我已经发送了所有响应!”),但在客户端失败(“响应超过了我的截止时间!”)。也有可能服务器决定在客户端发送完所有请求之前就完成。
元数据
元数据是有关特定 RPC 调用的信息(例如 认证详细信息),以键值对的形式存在,其中键是字符串,值通常是字符串,但也可以是二进制数据。
键不区分大小写,由 ASCII 字母、数字和特殊字符 -
、_
、.
组成,且不能以 grpc-
开头(这个前缀保留给 gRPC 本身)。二进制值键以 -bin
结尾,而 ASCII 值键则不以此结尾。
用户定义的元数据不被 gRPC 使用,这允许客户端将与调用相关的信息提供给服务器,反之亦然。
访问元数据是语言依赖的。