当前位置:网站首页>玩转gRPC—深入概念与原理
玩转gRPC—深入概念与原理
2022-07-05 07:18:00 【Barry Yan】
本篇文章属于一篇知识的捡漏和复盘类的文章,主要目的就是为了复盘一下gRPC的相关概念,并剖析其原理,相关知识点和使用大家可以参看之前的几篇文章:
以上的几篇文章都不同程度的讲述和RPC协议相关知识和Google开源的RPC框架gRPC的相关知识,但是可能都比较浅显和不成体系,因此想利用这篇文章系统深入的讲述下gRPC,下面开始:
1 使用gRPC的基本架构
由上图我们可以看出,使用gRPC通信的基本架构中基本分为五部分,他们分别是:
- Service:提供的服务
- Client:gRPC客户端
- gRPC Server:gRPC服务端接口
- gRPC Stub:gRPC客户端接口
- Proto Request/Proto Response(s):中间文件(代码/协议)
2 Protocol Buffers
2.1 什么是Protocol Buffers?
Protocol Buffers,是Google公司开发的一种数据描述语言,简称protobuf。
特点:
- 支持多种编程语言
- 序列化数据体积小
- 反序列化速度快
- 序列化和反序列化代码自动生成
2.2 Protocol Buffers和gRPC什么关系?
首先要说明的是gRPC是RPC协议是一种实现,是一个框架;Protocol Buffers,是Google公司开发的一种数据描述语言。
gRPC和Protocol Buffers的关系就好比浏览器和HTML的关系,不相互依赖,但是需要相互配合使用,才能达到最好的效果。
2.3 Protocol Buffers基本语法
Protocol Buffers是一个带有.proto
扩展名的普通文本文件。
协议缓冲区数据被构造为消息,其中每条消息都是一个小的信息逻辑记录,包含一系列称为字段的键值对。这是一个简单的例子:
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
一旦你指定了你的数据结构,你就可以使用协议缓冲区编译器protoc
从你的原型定义中以你喜欢的语言生成数据访问类。这些为每个字段提供了简单的访问器,例如name()
and set_name()
,以及将整个结构序列化/解析到原始字节的方法。
在普通的 proto 文件中定义 gRPC 服务,将 RPC 方法参数和返回类型指定为协议缓冲区消息:
// 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;
}
gRPC 使用protoc
特殊的 gRPC 插件从 proto 文件生成代码:将获得生成的 gRPC 客户端和服务器代码,以及用于填充、序列化和检索消息类型的常规协议缓冲区代码。
3 gRPC的四种服务提供方法
3.1 Unary RPC
一元 RPC,其中客户端向服务器发送单个请求并获得单个响应,就像正常的函数调用一样。
rpc SayHello(HelloRequest) returns (HelloResponse);
3.2 Server streaming RPC
服务器流式 RPC,其中客户端向服务器发送请求并获取流以读回一系列消息。客户端从返回的流中读取,直到没有更多消息为止。gRPC 保证单个 RPC 调用中的消息顺序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
3.3 Client streaming RPC
客户端流式 RPC,其中客户端写入一系列消息并将它们发送到服务器,再次使用提供的流。一旦客户端完成了消息的写入,它就会等待服务器读取它们并返回它的响应。gRPC 再次保证了单个 RPC 调用中的消息顺序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
3.4 Bidirectional streaming RPC
双向流式 RPC,双方使用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以按照他们喜欢的任何顺序读取和写入:例如,服务器可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取消息然后写入消息,或其他一些读取和写入的组合。保留每个流中消息的顺序。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse)
4 gRPC的生命周期
4.1 服务的提供
RPC服务的提供主要包括以上四种服务提供方法。
4.2 截止日期/超时
gRPC 允许客户端指定在 RPC 因错误而终止之前,他们愿意等待 RPC 完成多长时间DEADLINE_EXCEEDED
。在服务器端,服务器可以查询特定的 RPC 是否已超时,或者还剩多少时间来完成 RPC。
指定期限或超时是特定于语言的:一些语言 API 根据超时工作,而一些语言 API 根据期限工作。
4.3 RPC 终止
在 gRPC 中,客户端和服务器都对调用是否成功做出独立的本地判断,并且它们的结论可能不匹配。这意味着,例如,可能有一个 RPC 在服务器端成功完成但在客户端失败。服务器也可以在客户端发送所有请求之前决定完成。
4.4 取消 RPC
客户端或服务器都可以随时取消 RPC。取消会立即终止 RPC,以便不再进行任何工作。
5 gRPC通信原理
众所周知,gRPC是基于HTTP2的,而HTTP2又是一个相对HTTP1.1比较新的概念,因此在探究gRPC原理之前有必要先了解下HTTP2是怎样的。
5.1 HTTP2
HTTP/2 的规范于 2015 年5 月发布,旨在解决其前身的一些可扩展性问题,在许多方面改进了 HTTP/1.1 的设计,最重要的是提供了连接上的语义映射。
创建 HTTP 连接的开销很大。您必须建立 TCP 连接、使用 TLS 保护该连接、交换标头和设置等。HTTP/1.1 通过将连接视为长期存在的、可重用的对象来简化此过程。HTTP/1.1 连接保持空闲,以便可以通过现有的空闲连接发送到同一目的地的新请求。虽然连接重用缓解了这个问题,但一个连接一次只能处理一个请求——它们是 1:1 耦合的。如果要发送一条大消息,新请求必须要么等待它完成(导致 队列阻塞),要么更频繁地为启动另一个连接付出代价。
HTTP/2 通过在连接之上提供一个语义层:流,从而进一步扩展了持久连接的概念。流可以被认为是一系列语义连接的消息,称为 帧。流可能是短暂的,例如请求用户状态的一元流(在 HTTP/1.1 中,这可能等同于
GET /users/1234/status
)。随着频率的增加,它的寿命很长。接收者可能会建立一个长期存在的流,从而实时连续接收用户状态消息,而不是向 /users/1234/status 端点发出单独的请求。流的主要优点是连接并发,即在单个连接上交错消息的能力。流量控制
然而,并发流包含一些微妙的陷阱。考虑以下情况:同一连接上的两个流 A 和 B。流 A 接收大量数据,远远超过它在短时间内可以处理的数据。最终,接收者的缓冲区被填满,TCP 接收窗口限制了发送者。这对于 TCP 来说都是相当标准的行为,但这种情况对于流来说是不利的,因为两个流都不会接收更多数据。理想情况下,流 B 应该不受流 A 的缓慢处理的影响。
HTTP/2 通过提供 流控制 机制作为流规范的一部分来解决这个问题。流控制用于限制每个流(和每个连接)的未完成数据量。它作为一个信用系统运行,其中接收方分配一定的“预算”,发送方“花费”该预算。更具体地说,接收方分配一些缓冲区大小(“预算”),发送方通过发送数据填充(“花费”)缓冲区。接收方使用特殊用途的WINDOW_UPDATE帧向发送方通告可用的额外缓冲区 . 当接收方停止广播额外的缓冲区时,发送方必须在缓冲区(其“预算”)耗尽时停止发送消息。
使用流控制,并发流可以保证独立的缓冲区分配。再加上轮询请求发送,所有大小、处理速度和持续时间的流都可以在单个连接上进行多路复用,而无需关心跨流问题。
更智能的代理
HTTP/2 的并发属性允许代理具有更高的性能。例如,考虑一个接受和转发尖峰流量的 HTTP/1.1 负载平衡器:当出现尖峰时,代理会启动更多连接来处理负载或将请求排队。前者——新连接——通常是首选(在某种程度上);这些新连接的缺点不仅在于等待系统调用和套接字的时间,还在于在 发生TCP 慢启动时未充分利用连接所花费的时间。
相比之下,考虑一个配置为每个连接多路复用 100 个流的 HTTP/2 代理。一些请求的峰值仍然会导致新的连接被启动,但与 HTTP/1.1 对应的连接数相比只有 1/100 个连接。更笼统地说:如果 n 个 HTTP/1.1 请求发送到一个代理,则 n 个 HTTP/1.1 请求必须出去;每个请求都是一个有意义的数据请求/有效负载,请求是 1:1 的连接。相反,使用 HTTP/2 发送到代理的 n请求需要n 个流,但 不需要n 个 连接!
5.2 gRPC与HTTP2
gRPC 引入了三个新概念:通道、远程过程调用 (RPC) 和消息。三者之间的关系很简单:每个通道可能有很多 RPC,而每个 RPC 可能有很多消息。
通道是 gRPC 中的一个关键概念。HTTP/2 中的流支持在单个连接上进行多个并发会话;**通道通过在多个并发连接上启用多个流来扩展这个概念。**从表面上看,频道为用户发送消息提供了一个简单的界面;然而,在引擎盖下,大量的工程投入到保持这些连接的活力、健康和利用上。
通道代表到端点的虚拟连接,实际上可能由许多 HTTP/2 连接支持。RPC 与连接相关联(此关联将在后面进一步描述)。RPC 实际上是普通的 HTTP/2 流。消息与 RPC 相关联并作为 HTTP/2 数据帧发送。更具体地说,消息是在数据帧之上*分层的。*一个数据帧可能有很多 gRPC 消息,或者如果一个 gRPC 消息非常大它可能跨越多个数据帧。
6 总结
好了,到这里关于gRPC的讲解就差不多了,归根结底,gRPC是一个网络协议,既然是网络协议就难逃网络I/O,因此也正是I/O多路复用成就了HTTP2,进而成就了gRPC,下一篇文章,让我们深入浅出网络I/O模型!
参考文章:
https://www.cncf.io/blog/2018/07/03/http-2-smarter-at-scale/
https://grpc.io/blog/grpc-on-http2/
边栏推荐
- [software testing] 03 -- overview of software testing
- Three body goal management notes
- SD_ CMD_ SEND_ SHIFT_ REGISTER
- window navicat连接阿里云服务器mysql步骤及常见问题
- arcgis_ spatialjoin
- Don't confuse the use difference between series / and / *
- Application of MATLAB in Linear Algebra (4): similar matrix and quadratic form
- docker安装mysql并使用navicat连接
- PHY drive commissioning --- mdio/mdc interface Clause 22 and 45 (I)
- What if the DataGrid cannot see the table after connecting to the database
猜你喜欢
Ros2 - Service Service (IX)
Literacy Ethernet MII interface types Daquan MII, RMII, smii, gmii, rgmii, sgmii, XGMII, XAUI, rxaui
M2DGR 多源多场景 地面机器人SLAM数据集
PowerManagerService(一)— 初始化
Anaconda navigator click open no response, can not start error prompt attributeerror: 'STR' object has no attribute 'get‘
[untitled]
第 2 章:小试牛刀,实现一个简单的Bean容器
并发编程 — 死锁排查及处理
Chapter 2: try to implement a simple bean container
【idea】Could not autowire. No beans of xxx type found
随机推荐
arcgis_ spatialjoin
[software testing] 03 -- overview of software testing
Implementation of one-dimensional convolutional neural network CNN based on FPGA (VIII) implementation of activation layer
[framework] multi learner
new和malloc的区别
What is soda?
PostMessage communication
Reading literature sorting 20220104
C learning notes
Hdu1231 maximum continuous subsequence (divide and conquer or dynamic gauge or double pointer)
氢氧化钠是什么?
Steps and FAQs of connecting windows Navicat to Alibaba cloud server MySQL
And play the little chestnut of dynamic agent
HDU1231 最大连续子序列(分治or动规or双指针)
【软件测试】03 -- 软件测试概述
ImportError: No module named ‘Tkinter‘
PowerManagerService(一)— 初始化
程序中的负数存储及类型转换
npm install -g/--save/--save-dev的区别
Logical structure and physical structure