GRPC是什么?
在GRPC中,如果是本地对象,一个客户端程序能直接调用在不同机器上的服务器端程序的方法,更方便的创建分布式应用程序和方法。在许多的grpc系统中, grpc基于定义服务的理念,指定可与他们的参数和返回类型的方法。在服务端,服务器实现此接口,并运行一个grpc服务器处理客户端调用。在客户端,客户端有一个存根(在某些语言中称为客户端),提供与服务器相同的方法。
在各种环境下,GRPC客户端和服务器可以运行和彼此通信:从google内部服务器到自己桌面,并且能被任何grpc支持的语言写出来。例如,你能很轻松的用java创建grpc服务,客户端使用go/python/ruby来写。此外,google最新的api将有接口的grpc版本,让你轻松的构建google功能到你的程序。
使用协议缓冲区:
默认情况下,grpc使用协议缓冲区(protocol buffers),google成熟的序列化结构数据的开源机制(尽管可以用作其他数据格式,如json)。
第一步:
将你想要实例化的数据的结构在一个proto 文件里面:文件后缀为.proto。协议缓缓从区(protocol buffers)数据被构造成消息,其中每条消息都是包含一些列名值对被称为字段的逻辑记录.
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
一旦你定义了自己的数据结构,你就能使用协议缓冲区编译器proto从你的proto定义中使用你首选的语言生成数据访问类,为每个属性提供简单的访问器(像name(),set_name()),同时将方法序列化/解析整个结构到原始字节或者从原始字节序列化/解析出来。比如,你选择的语言是c++,运行上面的例子将会生成一个Person的类。你可使用这个类在你的程序中填充,序列化,检索Person协议缓冲消息。
定义grpc服务在普通的proto文件里面,使用rpc方法参数和指定的返回值类型作为协议缓冲消息。
// the greeter service definition
service Greeter {
rpc SayHello(HelloRequest) returns (HelloReply){}
}
// the request message containing the user's name
message HelloRequest{
string name = 1;
}
// the response message containing the greetings
message HelloReply {
string message = 1;
}
grpc使用proto 指定的grpc插件从你的proto文件生成代码。使用grpc插件,你将得到生成的grpc client和server code以及定期的填充,序列化,检索你的消息类型的协议缓冲代码。
GRPC概念
服务定义
像很多rpc系统一样,grps是基于服务定义的理念,指定用他们的参数和返回类型远程调用方法。默认情况下,grpc使用协议缓冲作为Interface Definition Language(IDL)来描述服务接口和有效载荷信息的结构。如果需要,可以使用其他替代品。
service HelloService {
prc SayHello(HelloRequest) return (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
grpc让你定义4种类型的service方法。
1.一元的rpc,客户端发送一个请求到服务器,并得到一个回应,就像一个普通的函数调用。
rpc SayHello (HelloRequest) returns (HelloResponse){}
2.rpc服务器流,客户端像服务器发送请求,获取流读取信息序列回来,客户端从返回的流读取,直到不再有消息为止。
rpc LogsOfReplies(HelloRequest) returns (stream HelloResponse)
3. rpc客户端流,客户端写一个消息序列并发送到服务器,再使用提供的流,一旦客户端完成了消息的写入,就等待服务器读取并返回响应。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
4. 双向流rpc双方发送序列使用读写信息流。这两个流独立运行,因此客户端和服务器可以按照自己喜欢的顺序读取或写入。如服务器可以在等待接收所有客户端消息写入响应之前,或者他可以交替读取消息,然后再写入消息,或者其他读写操作的组合。每条流中的消息顺序保持不变。
rpc BindHello(stream HelloRequest) returns (stream HelloResponse){}
使用RPC Surface
从服务定义在proto 文件开始,grpc提供协议缓冲编译器生成服务端和客户端代码。grpc调用者通常在客户端调用这些api,而在server端实现响应的api.
在服务端,服务端实现那些在service定义的方法以及运行一个grpc服务来处理客户端的调用。grpc基础设施解码即将传过来的请求,执行服务方法,并编码服务的响应。
在客户端,客户端有一个称为存根的本地对象(对于某些语言,首选的术语是客户端)实现相同方法作为服务。客户端能使用本地对象调用这些方法,本地对象在调用的时候包装请求参数在适当的协议缓冲消息类型。grpc看起来发送请求到服务器后再返回服务器的协议缓冲响应。
同步vs异步
同步grpc调用直到响应从服务器到达才阻塞,这与RPC渴望的过程调用的抽象最接近。另一方面,网络本质上是异步的,在许多情况下,它是有用的能够无阻塞当前线程启动RPC。
GRPC生命周期
一元rpc
grpc最简单的类型,当客户端发送单一请求并且得到单一的响应。
一旦客户端调用在存跟/客户端对象的方法,服务器被通知rpc与客户端的元数据一起调用此方法,方法名和指定的截止日期,如果适用的话。
服务器要么直接返回自己初始化的元数据(一定要在所有响应之前发送),或者等待客户端的请求消息-首先发送的是特定于应用程序的消息。
一旦服务器得到了客户端的请求消息,就会执行创建和填充其响应所需要的任何工作。然后返回响应(如果成功)到客户端,连同状态详细信息(状态码和可选的状态消息)和可选的跟踪元数据。
如果状态是OK,客户端得到响应,该响应完成客户端的调用。
rpc服务器流
rpc服务器流类,服务器在得到客户端的请求消息之后发送响应流。当服务器返回了所有的响应,服务器的状态详情(状态码和可选的状态消息)连同可选的追踪元数据一起返回以完成服务器端的响应。客户端随着服务器端响应的完成而完成。
rpc客户端流
rpc客户端流期待客户端发送请求流到服务器而不是发送单一的请求。服务器返回单一的响应,通常,但不一定是在接收到所有客户读请求之后,以及状态详细信息和可选的跟踪元数据。
双向的rpc
在双向rpc流中,再次调用是由客户端调用方法和服务器接收客户机元数据、方法名和截止日期发起的。服务器再次可以选择发送初始元数据,或者等待客户端开始发送请求。
接下来发生的事情取决于应用程序,因为客户端和服务器可以以任意顺序读写,流完全独立运行。因此,例如,服务器可以等待直到它接收到所有客户端消息,然后再写响应。或者服务器得到一个请求,然后发送一个响应然后客户端根据响应发送另一个请求。
期限/超时
grpc允许客户端指定多久都愿意等待一个rpc完成前终止DEADLINE_EXCEEDED错误。在服务器端,服务器可以查询某个特定的rpc已经超时或者还剩多少时间来完成rpc.
期限/超时,不同的编程语言是不同的,并不是所有的编程语言都有默认的期限。
rpc终止
在GRPC,客户端和服务器都进行独立的和本地呼叫的成功的决定,他们的结论可能不匹配。这意味着,例如,您可以在服务器端成功地完成一个RPC(“我已经发送了所有的响应”)!“但在客户端失败(在我的截止日期后回复)!“)。在客户端发送所有请求之前,服务器也可以决定完成。
取消rpcs
客户端或服务器可以在任何时候取消rpc,取消立即终止rpc,这样就不需要做进一步工作,取消不是撤销:取消前所做的更改不会回滚。
元数据
元数据是一种特定rpc调用(如授权详情)以值对形式存在的信息,key是string,value通常是string(但也可能是二进制数据)。元数据对grpc本身是不透明的,它允许客户机提供与服务器调用相关联的信息,反之亦然。
访问元数据是依赖与语言的。
通道
一个grpc通道提供连接grpc指定主机和端口,在创建客户端存跟(或者客户端)的时候使用。客户端可以指定渠道参数来修改grpc默认的行为,例如切换消息压缩。通道有状态:连接和空闲。
grpc认证
grpc被设计来可以在多种认证机制下工作,使它非常容易的安全的使用grpc与其他系统通信。你可以使用我们我们支持的认证机制:SSL/TLS基于或不基于google token的认证,或者你能插入自己的认证系统靠扩展我们提供的代码。