gRPC - 服务

277 阅读4分钟

这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

定义

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

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

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

方式

一元/单项 RPC

即客户端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。

rpc SayHello(HelloRequest) returns (HelloResponse);
  • 一旦客户端呗调用,服务器就会收到通知:RPC已经被调用,其中包括客户端的元数据、方法名称和指定的截止日期等。
  • 服务器可以立即返回自己的初始元数据(必须在所有响应之前发送),或者等待客户端的请求消息。到底哪个先发生,取决于具体的应用。
  • 一旦服务端获得客户端的请求信息,就会做所需的任何工作来创建或组装对应的响应。如果成功的话,这个响应会和包含状态码以及可选的状态信息等状态明细及可选的追踪信息返回给客户端 。
  • 如果响应状态为 OK,则客户端得到响应,在客户端完成调用

服务器流式 RPC

客户端向服务器发送请求并获取流以读取一系列消息。客户端从返回的流中读取,直到没有更多消息。gRPC 保证单个 RPC 调用中的消息排序。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

服务器流式 RPC 类似于一元 RPC,不同之处在于服务器返回消息流以响应客户端的请求。发送完所有消息后,服务器的状态详细信息(状态代码和可选状态消息)和可选的尾随元数据将发送到客户端。这样就完成了服务器端的处理。一旦客户端拥有服务器的所有消息,它就完成了。

客户端流式 RPC

其中客户端写入一系列消息并将它们发送到服务器,再次使用提供的流。一旦客户端完成写入消息,它等待服务器读取它们并返回其响应。gRPC 再次保证单个 RPC 调用中的消息排序。

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

客户端流式 RPC 类似于一元 RPC,不同之处在于客户端向服务器发送消息流而不是单个消息。服务器用一条消息(连同它的状态详细信息和可选的尾随元数据)进行响应,通常但不一定是在它收到所有客户端的消息之后。

双向流式 RPC

其中双方使用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以按照他们喜欢的任何顺序进行读写:例如,服务器可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取消息然后写入消息,或其他一些读取和写入的组合。保留每个流中消息的顺序。

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

双向流式 RPC ,调用由客户端调用方法来初始化,而服务端则接收到客户端的元数据,方法名和截止时间。服务端可以选择发送回它的初始元数据或等待客户端发送请求。

下一步怎样取决于应用,因为客户端和服务端能在任意顺序上读写 - 这些流的操作是完全独立的。

例如服务端可以一直等直到它接收到所有客户端的消息才写应答,或者服务端和客户端可以像"乒乓球"一样:服务端后得到一个请求就回送一个应答,接着客户端根据应答来发送另一个请求,以此类推。