文章目录
1.声明服务
像很多RPC机制,GRPC也是基于围绕声明一个服务的思想,指定一个可以被远程调用的包含参数和返回值的方法。
GRPC默认使用protocol buffers作为接口声明语言(IDL:interface definition language)用来描述service接口和承载message的结构。如果需要,也可以使用其他替代方案。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
GRPC可以声明四种类型的service方法
- client发送一个单一的request,service返回一个单一的response,就像普通的函数调用那样。
rpc SayHello(HelloRequest) returns (HelloResponse);
- client发送一个request到service,service返回一个可读取的序列化message流。client读取流直到service没有message返回。gRPC保证单个RPC调用中的消息排序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
- client写入一个序列化message并发送给service,一旦client停止写入message,client将等待service读取并返回response,gRPC再次保证单个RPC调用中的消息排序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
- 双向流RPC,其中双方使用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以按照它们喜欢的顺序进行读写:例如,服务器可以等待接收所有客户端消息,然后再写入响应,或者可以交替地读取消息,然后写入消息,或者其他读写组合。保留每个流中消息的顺序。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
2.使用API
从在.proto文件中声明一个service开始,GRPC提供了protocol buffers编译插件用来生成客户端和服务端的代码。gRPC开发者通常在客户端调用这些API,并在服务器端实现相应的API。
- 在服务端,server实现了在service声明的方法并返回了Grpc server用来处理client的调用。gRPC基础结构对传入的请求进行解码,执行服务方法,并对服务响应进行编码。
- 在客户端,client有一个本地对象叫做stub,实现了和service同样的方法。client可以使用这个本地对象调用这些方法,方法将调用的参数包装在适当的协议缓冲区消息类型中,发送请求到server,并返回server端的protocol buffer 响应。
3.同步和异步
在服务器收到响应之前阻塞的同步RPC调用最接近于RPC所期望的过程调用的抽象。另一方面,网络本质上是异步的,在许多情况下,能够在不阻塞当前线程的情况下启动RPC是非常有用的。
大多数语言中的gRPC编程API都有同步和异步两种风格。你可以在每种语言的教程和参考文档中找到更多信息。
4.RPC的生命周期
首先考虑最简单的RPC类型,其中客户端发送一个请求并返回一个响应。
- 一旦客户端调用了stub方法,就会通知服务器RPC已被调用,并带有客户端的元数据、方法名称和指定的截止日期(如果适用)。
- 然后,服务器可以立即发送回自己的初始元数据(必须在任何响应之前发送),或者等待客户端的请求消息。首先发生的是特定于应用程序的。
- 一旦服务器收到客户机的请求消息,它就会执行创建和填充响应所需的任何工作。然后将响应(如果成功)与状态详细信息(状态代码和可选状态消息)和可选的尾随元数据一起返回给客户端。
- 如果响应状态为OK,那么客户端将得到响应,从而完成客户端的调用。
5.服务器流RPC
服务器流式RPC类似于单次RPC,只是服务器响应客户端的请求返回消息流。发送所有消息后,服务器的状态详细信息(状态代码和可选状态消息)和可选的跟踪元数据将发送给客户端。这就完成了服务器端的处理。客户端在收到所有服务器消息后完成。
6.客户端流RPC
客户端流式RPC类似于一元RPC,只是客户端向服务器发送消息流而不是单个消息。服务器用一条消息(连同其状态详细信息和可选的尾随元数据)进行响应,通常但不一定是在收到所有客户端消息之后。
7.双向流RPC
在双向流RPC中,调用由调用方法的客户端和接收客户端元数据、方法名称和截止日期的服务器发起。服务器可以选择发回其初始元数据或等待客户端开始流式消息。
客户端和服务器端流处理是特定于应用程序的。由于这两个流是独立的,客户端和服务器可以按任何顺序读写消息。例如,服务器可以等到收到客户端的所有消息后再编写消息,或者服务器和客户端可以打“乒乓球”——服务器收到请求,然后发回响应,然后客户端根据响应发送另一个请求,依此类推。
8.结束/超时
gRPC允许客户端指定在RPC以DEADLINE_EXCEEDED错误终止之前,他们愿意等待RPC完成多长时间。在服务器端,服务器可以查询特定的RPC是否已超时,或完成RPC还剩多少时间。
指定截止日期或超时是特定于语言的:某些语言API根据超时(持续时间)工作,而某些语言API则根据截止日期(固定时间点)工作,并且可能有或可能没有默认截止日期。
8.RPC终止
在gRPC中,客户端和服务器都对调用的成功进行独立的本地判断,并且它们的结论可能不匹配。这意味着,例如,您可以有一个RPC在服务器端成功完成(“我已经发送了所有响应!”),但在客户端失败(“响应在我的最后期限之后到达!”)。服务器也可以决定在客户端发送所有请求之前完成。
10.取消RPC
客户端或服务器可以随时取消RPC。取消将立即终止RPC,以便不再执行任何工作。
11.Metadata
元数据是有关特定RPC调用的信息(如身份验证详细信息),其形式为键值对列表,其中键是字符串,值通常是字符串,但也可以是二进制数据。
元数据是有关特定RPC调用的信息(如身份验证详细信息),其形式为键值对列表,其中键是字符串,值通常是字符串,但也可以是二进制数据。
密钥不区分大小写,由ASCII字母、数字和特殊字符-、_、组成。并且不能以grpc-开头(这是为grpc本身保留的)。二进制值键以-bin结尾,而ASCII值键不以-bin结束。
gRPC不使用用户定义的元数据,它允许客户端向服务器提供与调用相关的信息,反之亦然。
对元数据的访问取决于语言。
12.Channels
gRPC通道提供到指定主机和端口上的gRPC服务器的连接。它在创建客户端Stub时使用。客户端可以指定通道参数来修改gRPC的默认行为,例如打开或关闭消息压缩。通道具有状态,包括已连接和空闲。
gRPC如何处理关闭通道取决于语言。某些语言还允许查询通道状态。
查看原文DOC