gRPC的结构
在我们搭建gRPC通信系统之前,首先需要知道gRPC的结构组成。
首先,需要一个server(服务器),它用来接收和处理请求,然后返回响应。
既然有server,那么肯定有client(客户端),client的作用就是向server发送请求,具体就是生成一个请求,然后把它发送到server,然后等待server的响应。
但是它们不必是一对一的关系,在整个系统里,可以有多个server,也可以有多个client。根据实际情况,一个应用程序可能是gRPC的server,也可能是gRPC的client,也可能两者都是。
gRPC里面server和client并不是直接通信的,gRPC可以使用protocol buffer定义的消息来生成代码。
当client发送请求的时候,它会和server端生成的代码进行交互;同样在client端也有生成的代码,client端生成的代码负责提供一个隧道,这个隧道被用来把client端生成的消息发送给server。
因为server和client两端都有生成的代码,所以如何序列化和反序列化,以及如何进行来回的传输等细节,我们都可以不了解。
但是为了让server和client端来回传输通信,我们还需要一个协议,传输协议就负责把消息来回的传递。所以它并不需要懂得这些消息的内容,生成的代码会负责理解这些消息,但是传输协议需要负责把消息从一端传递到另一端。
目前,好像gRPC只能使用Protocol Buffer这一个传输协议。但是gRPC在设计的时候,它的传输层是可插拔的,所以如果我们想把Protocol Buffer使用某种JSON或XML的协议替换掉,是可行的。如果你有特定的需求使用Protocol Buffer无法实现的话,那么你也可以创建自己的传输协议。
设计步骤
总共应该分三步。设计原则是从里到外(看上面结构图)。
所以:
首先我们应该定义消息(message)。这些消息使用Protocol Buffer来进行定义
定义完消息,我们使用Proto-c编译器来生成server和client端的代码,它们会负责把消息在两端之间来回传递
现在,我们就可以写client和server了。
gRPC 生命周期
gRPC或者RPC的生命周期可以参考上图。
首先,需要创建一个隧道,该隧道会包装实际用来传输消息的线路协议。
例如如果我们的server和client之间使用HTTP/2协议,那么这个隧道就会包装一个server和client之间的TCP连接。
这些隧道的优点是,它们只需要创建一次。一旦隧道创建了,你就可以在你应用程序的生命周期之内持续的使该隧道来回发送消息。
隧道建立好之后,就该创建client了。client也是可以复用的,不必每个rpc调用都重建client。但是在调用之前,我们需要把client建立好。
现在client进入隧道,这个client通常是提供给我们的,我们不需要自己实现任何代码。使用Proto-c编译消息定义生成的代码将会给我们提供client需要的一切。我们只需要提供隧道即可。
client创建好之后,client就准备好给server发送请求了。这一步是必须的,gRPC无法让server端初始化请求发送给client端,请求都是client端初始化的。
但是client初始化请求之后,server端是可以发送多个响应回来的,这个以后再说。这时,client可以随着请求发送一些metadata(元数据),这些metadata是关于请求的,但不是请求对象本身。
请求被发送以后呢,server可以(但不是必须)把metadata返回。所以,你实际上可以在client和server之间进行这种“预约对话”。client可以发送一些metadata,然后server可以把一些metadata发送回来,这些都是发生在server开始处理请求之前。
生命周期的最后一部分就是发送和接收消息。就以简单的情况为例,现在server就应该把响应发送回去了,因为client已经发送了请求,所以响应就是要返回。
注意,关于metadata需要注意的是,gRPC内置的身份认证系统是用来做client和server的身份认证的。
但是这个metadata也为你提供了检查实际用户身份的机制。所以,如果你需要认证或者授权实际用户,就需要在RPC请求这个级别来实现。也就是在这里。
如果是client和server的身份认证,以后再写。。