Bootstrap

第一节 gRPC概述

目录

一、gRPC简介

二、基本概念

(一)gRPC和proto使用基本流程

(二)服务定义 Service Definition

(三)API使用简介

(四)同步调用和异步调用

(五)RPC的生命周期

1、Unary RPC 简单RPC调用(一元RPC)

2、Server Stream RPC 服务端流式调用

3、Client Stream RPC 客户端流式调用

4、Bidirectional Streaming RPC 双向流式调用

(六) Deadlines/Timeouts  截止日期/超时

(七)RPC termination 终止RPC

(八) Cancelling an RPC 取消RPC

(九) Metadata  元数据

(十) Channels 通道



一、gRPC简介

         gRPC 是谷歌公司开源的基于Protobuf和HTTP2.0的RPC框架(RPC Remote Procedure Call,远程过程调用),可知支持跨语言的rpc调用,比如:Java rpc Java,Java rpc C#,Java rpc C++, Java rpc python等。同时,它以可插拔的方式对对负载平衡、跟踪、健康检查和身份验证进行支持。另外,它还适用于分布式计算的最后一公里:将设备、移动APP和浏览器都连接到后端服务。本节主要介绍gRPC协议的核心概念。

        谈起gRPC,就离不开protocol buffers.这个是谷歌开源的二进制RPC通讯协议,提供了一种描述通讯协议的语言:IDL,Interface Definition Language 接口描述语言,通过编写接口协议,Protobuf可以自动生成多种语言的RPC通讯代码,比如:Java,C++,C#,go,python,node等。我们的gRPC就是基于这个协议去定义rpc服务和传递请求响应消息的。

二、基本概念

(一)gRPC和proto使用基本流程

        在gRPC中,一个客户端可以像调用本地方法一样调用远程服务器中的方法,这样就可以让你更方便的创建分布式应用和服务。跟大多数RPC系统一样,gRPC是基于声明式的方式去定义远程过程调用,指定方法名、参数以及返回值。服务端会实现声明的接口并编写方法体去处理相应的请求。客户端通过stub保存定义的方法,客户端通过stub中保存的方法进行远程调用。

(如下图)

大体流程如下

第一步:程序员首先编写xxx.proto文件

第二步:通过proto工具生成服务接口和消息(序列化)

第三步:copy相应内容到服务端和客户端,服务端要实现接口,客户端通过stub进行调用。

用定义的message进行消息通信。

你可以用不同语言的工具生成代码,并进行跨语言的调用。

(二)服务定义 Service Definition

如上所述,我们要使用gRPC,首先要使用proto文件定义相应的rpc servic和message.

如下所示,我们定义hello.proto

//声明 rpc 服务接口
//关键字: service 声明需要生成的服务接口"类"
service Greeter {
    // 关键字: rpc 声明服务方法,包括方法名、请求消息(请求体)、相应消息(响应体)
    rpc SayHello(HelloRequest) returns (HelloResponse);
}
//声明请求、响应消息
//关键字: message 声明请求体和响应体
message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string message = 1;
}

gRPC允许你定义4种类型的服务方法:

第1种:一元RPC调用,也叫简单RPC调用。客户端向服务端发送单个请求,服务端返回单个响应,就像调用普通方法一样。

rpc SayHello(HelloRequest) returns (HelloResponse);

第2种:服务端流式RPC. 客户端向服务端发送单个请求,服务端以流的方式返回一系列消息。客户端从流中读取消息,直到没有更多的消息。当然,返回的消息当然不是乱序的,gRPC保证单个请求中的消息顺序 。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

第3种:客户端流式RPC调用。客户端向服务端请求一系列的消息,一旦客户端完成消息写入,就会等待服务端读取所有消息并处理它们。gRPC同样会保证单个请求中消息的顺序性。

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

第4种:双向流式调用。顾名思义,就是客户端和服务端均以流的方式进行读写消息。这两个流式完全独立的,因此,服务端和客户端可以按照他们喜欢的方式写入和读取流。比如:服务端可以在等待所有的客户端消息发送到后,再处理;也可以交替读取请求、写入响应信息等。当然,每个流中的消息顺序是可以保证的。

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

(三)API使用简介

        从.proto定义服务开始,gRPC会提供相关的插件生成对应的客户端和服务端代码。客户端去调用相应的API,而服务端去实现相应的API.

        服务端,实现.proto文件中service声明的方法,并启动一个gRPC服务端去处理客户端的调用。gRPC框架会解码请求的消息,执行服务方法,并编码服务响应消息。

        客户端,客户端用stub来完成.proto文件中声明的rpc服务调用的实现(框架生成相关实现)。

客户端可以像调用本地方法一样发起远程调用。gRPC框架会编码请求消息,发送请求,解码服务端的响应消息。       

(四)同步调用和异步调用

        同步调用会阻塞在程序调用处直到服务端响应响应的消息,这个是最贴近本地方法调用的方写文章-CSDN博客式。但是,从另外一方面来讲,网络是异步的,在许多情况下,异步非阻塞的方式去调用远程服务时很有用的一种方式。

(五)RPC的生命周期

        在本小节中,将呈现gRPC客户端调用服务端方法时到底发生了什么。当然,本小节也是关键点的概述,具体的实现示例,请参看相关语言的示例。

1、Unary RPC 简单RPC调用(一元RPC)

客户端发送单个请求消息,服务端响应单个消息。这一种是最简单的RPC调用。

1>一旦客户端通过stub调用了一个方法(向服务端发起请求),服务端就会收到包含客户端RPC调用元数据、方法名以及调用超时(如果需要)信息的通知。

2>然后服务端可以选择是立即返回服务端元数据(在任何响应之前)或者等待客户端的消息。(看具体的应用逻辑)

3>一旦服务端接收到客户端的请求消息,他就会做必要的处理。然后将响应状态和可选的元数据返回给客户端

4>如果响应状态是 OK,然后客户端就会获取response以完成响应的调用。

2、Server Stream RPC 服务端流式调用

        服务器流式RPC类似于简单RPC调用,不同之处在于服务端是以流的方式返回的一系列消息。当发送完所有响应消息后,服务端的状态详细信息(状态码和状态消息)和可选元数据信息会发送给客户端。

        一旦客户端等到服务端所有消息返回后就会结束调用。

3、Client Stream RPC 客户端流式调用

        客户端流失RPC同样类似简单RPC调用,不同之处在于客户端以流的方式发送一系列消息,而不是只发送单个消息。但是,服务端只返回一个响应消息,这个响应可以是服务端收到所有消息之后,也可以在收到客户端部分消息时。

4、Bidirectional Streaming RPC 双向流式调用

        在双向流式RPC调用中,RPC调用是双方发起的。服务端可以选择立即向客户端发送其初始元数据或者等待客户端客户端的消息流。

        客户端和服务端的流是相互独立的,客户端和服务端可以按照任意顺序去读写消息。比如:服务端可以等待收到所有的客户端消息后再写入服务端消息,也可以像“打乒乓球”一样来一条客户端消息,处理一个,然后响应一条服务端消息,然后客户端再发送另一条消息,依次类推。

(六) Deadlines/Timeouts  截止日期/超时

        gRPC允许客户端指定在远程调用发生DEADLINE_EXCEEDED错误终止后愿意等待多长时。间。在服务端,则可以查询特定的RPC是否超时,或者还剩下多少时间来完成RPC.

        指定截止日期或者超时是收到语言特性限制的,某些语言的API会根据超时( 请求持续时间)来工作,有的语言的API会根据截止时间(固定时间点)来工作(有的语言有默认截至日期而有的没有)。

(七)RPC termination 终止RPC

        在gRPC中,客户端和服务端是可以独立RPC调用进行成功与否的判断的,这就导致了客户端和服务端对调用结果得出的结论是不一致的。这就意味着,如果你的调用在服务端成功完成了(“我已经发送我所有的响应”),但是客户端会提示失败(“响应在我指定的截止日期之后到达”)。服务端也有可能在客户端发送完所有请求消息之前完成。

(八) Cancelling an RPC 取消RPC

        客户端或服务器都可以随时取消 RPC。取消会立即终止 RPC,以便不再进行进一步的工作。

【特别注意】:取消之前的所做的更改不会回滚。

(九) Metadata  元数据

        元数据是以键值对列表的形式描述的特定RPC调用信息,比如身份验证详细信息。其中,键是字符串,值通常是字符串也可以是二进制数据。元数据对gRPC本身是不透明的(即是可以看到并可以设置的) ---- 它允许客户端提供与服务端调用的相关信息,反之亦然。

【注意】:对元数据的访问,取决于语言特性。

(十) Channels 通道

        gRPC通道提供了一条链接到指定主机和端口号的服务端的链接。他在创建客户端stub的时候使用。客户端可以指定通道参数来修改gRPC的默认行为,例如:打开或者关闭消息压缩。一个通道是有连接和空闲两个状态的。

        gRPC如何处理通道关闭,取决于语言。有的语言允许查询通道状态。

;