社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
原文链接。日常学习,若有错误,欢迎指正。
像许多RPC系统,gRPC基于一个基本思想,定义一个服务,明确规定接口的参数和返回值。默认情况下,gRPC使用PB作为它的接口定义语言。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
gRPC可以定义4种类型的服务方法:
rpc SayHello(HelloRequest) returns (HelloResponse){
}
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}
接下来我们将在RPC生命周期中详细查看不同类型的RPC
从 .proto 文件的服务定义开始,gRPC提供了protocol buffer编译器插件来生成客户端和服务端代码。gRPC用户在客户端调用这些API,服务端实现相应的代码。
同步RPC调用会在响应到达前阻塞(这也是RPC抽象概念里最渴望的)。在另一方面,网络本质上是异步的,并且在许多场景中,不阻塞当前线程的RPC是很有用的。
在许多语言中,gRPC编程都是同时支持同步调用和异步调用。你可以在每个语言的指南中找到更多相关信息。
现在让我们详细看下gRPC客户端调用gRPC服务端方法发生了什么。
首先让我们看下RPC中最简单的类型:客户端发送单个请求并得到单个响应。
server-streaming RPC和我们简单的例子是相似的,除了服务端在得到客户端请求消息后会返回一连串回复。在发送完所有的回复消息 ,服务端的状态详情(例如状态码和可选的状态消息)以及可选的尾部元数据后,服务端就完成了它的任务。客户端这里一旦接收到了服务端所有的回复后就完成了调用。
client-streaming RPC和简单例子也是相似的,除了客户端发送给服务端的是一连串请求消息而不是单个请求消息。典型的但不是必须的,服务端在接收到所有的客户端请求后,返回单个回复消息,以及状态详细和可选的尾部元数据。
在一个bidirectional streaming RPC中,再一次的客户端初始化调用方法,服务端接收到客户端发送的元数据,方法名称和deadline。服务可以选择发送回初始化元数据或者等待客户端开始发送请求。
接下来发生什么依赖于应用程序,客户端和服务端可以用任意顺序读写消息-流操作直接是完全相互独立的。例如,服务端可以在写回复消息之前等待直到它接收到所有的客户端消息,或者服务端和客户端可以 "ping-pong": 服务端获取一个请求,然后发送 一个响应,客户端根据回复发送另一个请求等等 。
gRPC允许客户端去定义它们愿意等一个RPC多久去完成在一个RPC被错误DEADLINE_EXCEEDED终止之前。在服务端,服务可以查询去看是否一个特定的RPC已经超时了,或者还剩多少时间去完成RPC。
dealine和timeout的定义方式不同语言之间是不同的。例如,不是所有的语言都有一个默认的deadline,一些语言的APIs就deadline(一个固定的时间点)工作,一些语言的APIs就timeouts工作(时间区间)。
在gRPC中,客户端和服务端有独立的和本地的确定关于调用是否成功,并且它们的结论不一定是一致的。这意味着,你可以有一个RPC在服务端成功完成了(我已经成功发送了我所有的回复),但是在客户端失败了(回复在我的deadline之后到达了)。这也是有可能的一个服务在客户端发送完它所有的请求之前决定完成RPC调用 。
客户端和服务端都可以在任意时间取消RPC调用。一个取消立即终止RPC调用,以致不再有工作继续执行。它不是一个"undo": 在取消前执行的工作不会被回滚。
Metadata关于一个特定RPC调用的信息(例如授权详情),它的形式是一列key-value键值对(key是字符串,value通常是字符串,当然也可以是二进制数据)。元数据对gRPC本身是不透明的-它在调用中让客户端提供信息给服务端,反之也是一样。
访问元数据是语言相关的。
一个gRPC channel提供了一个向特定主机和端口服务的连接,并且被使用当创建了一个client stub。客户端可以定义channel参数去调整gRPC的默认 行为,例如开或者关消息压缩。一个channel有状态,包括connected和idle。
gRPC是如何处理关闭的channel是语言相关的。一些语言也禁止查询channel状态 。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!