以下摘自官方
一句话定义
一个高性能,开源的通用RPC框架。基于HTTP/2协议设计。
特点
1、gRPC 是一个现代开源的高性能远程过程调用 (RPC) 框架,可以在任何环境中运行。
2、可以通过对负载平衡、跟踪、健康检查和身份验证的可插拔支持有效地连接数据中心内和跨数据中心的服务。
3、适用于分布式计算的最后一英里,将设备、移动应用程序和浏览器连接到后端服务。
信息交互
gRPC默认使用Protocol Buffers作为其接口定义语言 (IDL)和底层信息交互格式。Protocol Buffers是谷歌的成熟的开源的用于序列化结构化的数据,当然也可以使用其他数据格式(如JSON)。
proto文件
1、使用Protocol Buffer的第一步是定义要序列化的数据的结构在proto文件中。是一个.proto结尾的text文件。Protocol buffer数据被构造为message,每个message都是包含一系列name-value对的信息的小的逻辑记录,被叫做字段。例如:
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
2、指定数据结构后,用protocol buffer编译器protoc,从proto定义生成您的首选语言中的数据访问类。这些为每个字段提供简单的访问器,也是序列化整个结构体为原始字节或者解析原始字节为结构体的方法。如果使用go语言,编译器生成对应的结构体类型,可以在应用程序中使用这个结构体填充、序列化、检索这个类型的protocol buffer messages。
3、在proto文件中指定 gRPC services,使用rpc参数和返回的类型指定protocol buffer messages。
// The greeter service definition.
service Greeter {
// Sends a greeting
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;
}
4、gRPC使用指定的gRPC插件从proto文件中生成代码,将生成 gRPC的客户端和服务端的代码,以及用于填充、序列化和检索你的消息类型的常规protocol buffer代码。
gRPC是基于服务的思想
像许多RPC系统一样,gRPC基于定义服务的思想,指定可以通过参数和返回类型远程调用的方法。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
四种服务方法
1、客户端向服务器发送单个请求并获得单个响应的机构RPC,就像正常函数调用一样。
rpc SayHello(HelloRequest) returns (HelloResponse);
2、 服务器streaming传输RPC,客户端将请求发送到服务器并获取读取一系列消息的流。客户端从返回的流读取,直到没有更多的消息。GRPC保证在单个RPC调用中的消息排序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
3、客户端streaming RPC,客户端写一系列消息并将它们发送到服务器,再次使用提供的流。一旦客户端写入邮件,它会等待服务器读取它们并返回其响应。再次GRPC再次保证在单个RPC呼叫中的消息排序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
4、双向流式RPC,双方使用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以以其相同的顺序读取和写入。例如,服务器可以等待接收到所有的客户端消息后才写入响应,或者当他在写消息时候也能读消息,或者其他读写的组合。每个流中的消息顺序被保留。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
使用API
从Service定义开始,GRPC提供生成客户端和服务器端代码的协议缓冲区编译器插件。 GRPC用户通常在客户端调用这些API并在服务器端实现相应的API。
在服务器端,服务器实现服务声明的方法,并运行GRPC服务器以处理客户端调用。 GRPC基础架构对传入请求进行解码,执行服务方法,并编码服务响应。
在客户端,客户端具有称为存根的本地对象(对于某些语言,首选术语是客户端),其实现与服务相同的方法。然后,客户端可以在本地对象上调用这些方法,将调用的参数包装在适当的protocol buffer message类型中,gRPC负责向服务器发送请求并返回服务器的protocol buffer 响应。
同步和异步
同步RPC调用一直阻塞直到从服务端响应到达客户端,是最接近RPC所期望的过程调用的抽象。网络本质上是异步的,在很多情况下,能够在不阻塞当前线程的情况下启动rpc是很有用的。大多数语言中的gRPC编程API都有同步和异步两种风格。你可以在每种语言的教程和参考文档中找到更多信息(完整的参考文档即将发布)。
RPC生命周期
这里能更详细地了解当gRPC客户机调用gRPC服务器方法时发生了什么。
一元RPC
首先考虑最简单的RPC类型,其中客户机发送单个请求并返回单个响应。
1、一旦客户端调用stub方法,服务器就会被通知RPC已经被调用(invoked)了,该调用使用了客户端的元数据、方法名以及指定的截止日期(如果适用的话)。
扩展:stub方法:stub code是占坑的代码,桩代码给出的实现是临时性的/待编辑的。它使得程序在结构上能够符合标准,又能够使程序员可以暂时不编辑这段代码。
2、然后,服务器可以直接返回它自己的初始元数据metadata(必须在任何响应之前发送),或者等待客户机的请求消息。首先发生的是特定于应用程序的。
3、一旦服务器获得了客户机的请求消息,它就会执行创建和填充响应所需的任何工作。然后将响应(如果成功)连同状态详细信息(状态代码和可选的状态消息)和可选的跟踪元数据返回给客户端。
4、如果响应状态为OK,则客户端将获得响应,从而完成客户端上的调用。
服务端streaming RPC
服务器流RPC类似于一元RPC,不同的是服务器返回一个消息流来响应客户机的请求。在发送所有消息之后,服务器的状态详细信息(状态代码和可选的状态消息)和可选的跟踪元数据被发送到客户端。这就完成了服务器端的处理。客户端拥有所有服务器的消息后就完成了。
客户端streaming RPC
客户端流RPC类似于一元RPC,不同之处是客户端向服务器发送消息流而不是单个消息。服务器用一条消息(连同它的状态详细信息和可选的跟踪元数据)响应,通常但不一定是在它收到所有客户端消息之后。
双向流 RPC
双向流中,调用通过客户端发起调用方法,服务端接收到客户端的元数据,方法名和截止日期,服务器可以选择发回其初始元数据或等待客户端开始流消息。
客户端和服务器端流处理是特定于应用程序的。由于这两个流是独立的,客户端和服务器可以以任何顺序读写消息。例如,一个服务器可以等到它得到了所有客户的消息写它的消息之前,或者服务器和客户端可以像玩乒乓一样,服务器收到一个请求,然后发回一个响应,再根据客户端的响应发送另一个请求,等等。
截止时间/超时
gRPC允许客户端指定他们愿意等待RPC完成多长时间,直到RPC被一个DEADLINE EXCEEDED错误终止。在服务器端,服务器可以查询特定的RPC是否超时,或者还剩下多少时间来完成RPC。
指定截止日期或超时是特定于语言的,一些语言api是基于超时(持续时间)的工作方式,一些语言api的工作有一个截止日期(一个固定的时间点),可能有的语言api也可能没有默认的截止日期。
RPC终止
在gRPC中,客户端和服务器都对调用是否成功做出独立和自身的判断,所以他们的结论可能并不一致。这意味着,例如,你可以拥有一个在服务器端成功完成的RPC响应,但是客户端提前关闭。服务器也可能在客户端发送完所有请求之前决定是否完成。
取消一个RPC
客户端或服务器都可以在任何时候取消RPC。取消会立即终止RPC,这样就不需要做进一步的工作了。取消之前所做的操作不会回滚!
Metadata
元数据是以键-值对列表的形式显示的关于特定RPC调用的信息(比如身份验证细节),其中键和值通常都是字符串,但也可以是二进制数据。Metadata对于gRPC是不透明的。它允许客户端提供与服务器调用相关联的信息,反之亦然。访问元数据依赖于语言。
通道
gRPC通道提供到指定主机和端口的gRPC服务器的连接。它在创建客户端stub时使用。客户端可以指定通道参数来修改gRPC的默认行为,比如打开或关闭消息压缩。通道有状态,包括已连接和空闲。
gRPC如何关闭通道取决于语言。一些语言还允许查询通道状态。
Q&A
1、什么是gRPC?
gRPC是一个可以在任何地方运行的现代开源远程过程调用(RPC)框架。它使客户机和服务器应用程序能够透明地通信,并使构建连接的系统变得更容易。
2、gRPC全称?
gRPC Remote Procedure Calls
3、我们为啥要用gRPC?
主要场景:
(1)低延迟,高度可扩展,分布式系统。
(2)开发与云服务器通信的移动客户端。
(3)设计一个新的协议,需要准确、高效和独立的语言。
(4)分层设计,以支持扩展。身份验证、负载均衡、日志记录和监控等。
4、谁在用gRPC?
gRPC是云本地计算基金会(CNCF)的一个项目。谷歌长期以来一直在gRPC中使用大量的底层技术和概念。当前的实现正在谷歌的云产品和谷歌面向外部的api中使用。Square、Netflix、CoreOS、Docker、CockroachDB、Cisco、Juniper Networks和许多其他组织和个人也在使用它。
5、gRPC发展?
gRPC最初是由谷歌创建的,它使用一个称为Stubby的通用RPC基础设施来连接运行在其数据中心内部和跨数据中心的大量微服务,已经有十多年了。2015年3月,谷歌决定构建Stubby的下一个版本,并将其开源。其结果就是gRPC,它现在在谷歌之外的许多组织中被使用,为从微服务到计算(移动、网络和物联网)的最后一英里的用例提供动力。
6、gRPC支持哪些语言?
7、快速开始?
8、gRPC的license?
grpc/LICENSE at master · grpc/grpc · GitHub
9、官方文档?
10、Road Map?
GitHub - grpc/proposal: A repository for gRFCs
11、gRPC支持多久?
gRPC项目不做LTS版本。考虑到上面的滚动发布模型,我们支持当前的、最新的版本和更早的版本。这里的支持意味着bug修复和安全修复。
12、版本控制指南?
grpc/versioning.md at master · grpc/grpc · GitHub
13、发布时间表?
grpc/grpc_release_schedule.md at master · grpc/grpc · GitHub
14、漏洞报告?
proposal/P4-grpc-cve-process.md at master · grpc/proposal · GitHub
15、如何在浏览器中使用?
https://github.com/grpc/grpc-web
16、我可以用我喜欢的数据格式(JSON, Protobuf, Thrift, XML)使用gRPC吗?
是的。gRPC被设计为可扩展的,以支持多种内容类型。最初的发行版包含了对Protobuf的支持,以及对其他内容类型(如FlatBuffers和Thrift)的外部支持,它们处于不同的成熟度级别。
17、能在service mesh中使用gRPC吗?
是的。gRPC应用程序可以像其他应用程序一样部署在服务网格中。gRPC还支持xDS api,这使得在没有sidecar proxy(一种设计模式)的情况下,可以在服务网格中部署gRPC应用程序。这里列出了gRPC中支持的无代理服务网格特性。https://github.com/grpc/grpc/blob/master/doc/grpc_xds_features.md
18、gRPC如何帮助移动应用程序开发?
gRPC和Protobuf提供了一种简单的方法来精确定义服务,并自动为iOS、Android和提供后端服务的服务器生成可靠的客户端库。客户端可以利用先进的流和连接特性,这有助于节省带宽,在更少的TCP连接中做更多的事情,并节省CPU使用和节能。
19、为什么GRPC比HTTP/2的任何二进制BLOB更好?
这很大程度上就是gRPC所面临的问题。然而,gRPC也是一组库,它们将提供跨平台的一致的高级特性,而普通的HTTP库通常不提供这些特性。这些特性的例子包括:
(1)与应用程序层的流控制交互
(2)级联call-cancellation
(3)负载平衡和故障转移
20、GRPC为什么比REST更好或差?
GRPC在很大程度上在HTTP/2上遵循HTTP语义,但我们显式允许全双工流。我们与典型的REST约定不同,因为我们在调用分派期间出于性能考虑使用静态路径,因为从路径、查询参数和负载体解析调用参数会增加延迟和复杂性,我们还形式化了一组错误,我们认为这些错误比HTTP状态码更直接适用于API用例。