共计 2819 个字符,预计需要花费 8 分钟才能阅读完成。
简介
gRPC 是一个高性能、开源和通用的 RPC 框架,面向挪动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,别离是:grpc, grpc-java, grpc-go. 其中 C 版本反对 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 反对。
gRPC 基于 HTTP/2 规范设计,带来诸如双向流、流控、头部压缩、单 TCP 连贯上的多复用申请等特。这些个性使得其在挪动设施上体现更好,更省电和节俭空间占用。
gRPC 是什么?
在 gRPC 里 客户端 利用能够像调用本地对象一样间接调用另一台不同的机器上 服务端 利用的办法,使得您可能更容易地创立分布式应用和服务。与许多 RPC 零碎相似,gRPC 也是基于以下理念:定义一个 服务,指定其可能被近程调用的办法(蕴含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来解决客户端调用。在客户端领有一个 stub(存根)可能像服务端一样的办法。
gRPC 客户端和服务端能够在多种环境中运行和交互 – 从 google 外部的服务器到你本人的笔记本,并且能够用任何 gRPC 反对的语言来编写。所以,你能够很容易地用 Java 创立一个 gRPC 服务端,用 Go、Python、Ruby 来创立客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很容易地将 Google 的性能集成到你的利用里。
应用 protocol buffers
gRPC 默认应用 protocol buffers,这是 Google 开源的一套成熟的构造数据序列化机制(当然也能够应用其余数据格式如 JSON)。正如你将在下方例子里所看到的,你用 proto files 创立 gRPC 服务,用 protocol buffers 音讯类型来定义方法参数和返回类型。你能够在 框架协定篇章 中找到更多对于 Protocol Buffers 的材料。
上面是 protobuf 的一个简略的例子:
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
当咱们调用命令行来将下面的 protobuf 文件转化为 Python 代码后,此时将会生成一个 Person 类,而后对其进行实例化和字段的填充。
留神:
这里最好应用 proto3 版本,绝对于 proto2,新版本的 protobuf 定义更加简略,并且支持性更加欠缺。
参考文档:gRPC 官网文档中文版
gRPC 的定义
gRPC 通过 Protocol Buffer 来规定客户端调用服务端的接口数据结构和发送的音讯内容:
service HelloService {rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {string greeting = 1;}
message HelloResponse {string reply = 1;}
gRPC 的定义有以下几种形式:
- 一元 RPC,相似于一般的办法调用,发送一个申请,而后服务端返回一个响应:
rpc SayHello(HelloRequest) returns (HelloResponse);
- 服务端流式 RPCs:客户端发送一个申请,并取得一个流式响应的信息,客户端不停的进行读取,直到全副读取结束。gRPC 通过独自的调用实现了保障了音讯的排序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
- 客户端流式 RPCs:客户端发送一个流式的音讯申请,当客户端实现所有字节流的发送后,期待服务端实现音讯的读取并返回响应信息。同样的,也是通过独自的调用来保障音讯的程序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
- 双向流式 RPCs:客户端和服务端都通过读取和发送字节流来发送音讯序列。两个字节流的操作都是独立的,因而客户端和服务器能够自定义音讯程序。而服务端对于音讯的收发也能够交替执行。每个音讯的程序在底层都进行了保留。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
RPC 的生命周期
不同类型的 RPC 流程
一元 RPC
首先咱们先看看 最简略的 RPC 流程是如何的:
1. 当客户端调用了 stub 办法时,告诉服务端对指定接口的调用,通知服务端对应的办法名并指定 过期工夫(非必要)。
2. 服务端此时能够发送响应数据前发送的 metadata(该数据必须在 response 之前被发送),或者期待所有的音讯都被接管到了。对于该流程的指定,咱们能够通过程序来进行自定义。
3. 当服务端获取了所有的申请信息,若调用的整个过程没有抛出异样,此时将返回 response,并依据程序设定,返回尾部 metadata。
服务端流式 RPC
相似于上述的 一元 RPC,不同点是服务端返回的音讯为流式响应。在发送完所有的响应信息与状态信息(状态码以及其它相干信息)之后,会返回尾部 metadata。此时服务端实现响应。而客户端的响应实现须要在其接管完所有的响应信息。
客户端流式 RPC
客户端流式 RPC 也相似于 一元 RPC,不同点就是客户端通过发送流式音讯来进行申请。而服务端通过返回繁多模式的音讯来实现响应。
双端流式 RPC
双端流式 RPC 中,客户端和服务端都采纳流式的音讯进行收发。
此时客户端和服务端对于音讯的解决须要程序本身进行指定。两个流式 message 互相独立,因而能够自定义音讯解决流程。例如,服务端能够在接管完所有的流式信息后再去返回响应信息;或者服务端和客户端都进行 ping-pong 的响应:服务端在接管到流式申请的时候马上进行响应,而后客户端在接管到响应后再持续逻辑上的解决并持续发送申请。
目前来说,这个看起来比拟好使
RPC 的完结阶段
截止工夫和超时响应
gRPC 容许客户端指定响应的超时工夫,并在超时的时候抛出 DEADLINE_EXCEEDED
的异样。对于 server 端方面,服务端能够查问指定的 RPC 是否超时响应,或者是说离超时响应的工夫还有多久。
RPC 的 termination 状况
当咱们实现了一个响应的时候,服务端示意:我曾经实现了所有字节流的发送,然而客户端却说本人没有胜利接管到响应信息。这可能是因为客户端还没发送结束,服务端曾经认为整个申请的流程曾经完结了。
勾销 RPC 流程
咱们也能够在任何不开心的时候,间接把这个流程给关了。o(*~▽~*)ブ
相干概念阐明
Metadata
Metadata 是针对特定某个 RPC 的响应信息(例如 平安认证信息),该字段以 key-value 作为本身的数据结构。
Chanels
gRPC 通过管道来进行服务端和客户端的连贯。客户端能够指定参数来对 gRPC 的默认行为进行更改,例如是否对音讯进行压缩。管道同样有其对应的状态:connected
(正在连接中)或 idle
(闲暇状态)。