gRPC入门学习之旅(一)
gRpc简介
gRPC 是Google公司开发的基于HTTP/2设计,面向移动的一个高性能、开源和通用的 RPC 框架,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。
gRpc官网地址:https://www.grpc.io
gRpc中文文档地址:http://doc.oschina.net/grpc
gRPC是一款RPC框架,那么先了解Rpc是什么。
Rpc基本概念
RPC(Remote Procedure Call)远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,简单的理解是一个节点请求另一个节点提供的服务。RPC只是一套协议,基于这套协议规范来实现的框架都可以称为 RPC 框架,比较典型的有 Dubbo、Thrift 和 gRPC。
RPC 机制和实现过程
RPC 是远程过程调用的方式之一,涉及调用方和被调用方两个进程的交互。因为 RPC 提供类似于本地方法调用的形式,所以对于调用方来说,调用 RPC 方法和调用本地方法并没有明显区别。
RPC的机制的诞生和基础概念
1984 年,Birrell 和 Nelson 在 ACM Transactions on Computer
Systems 期刊上发表了名为“Implementing remote procedure calls”的论文,该文对 RPC 的机制做了经典的诠释:
RPC 远程过程调用是指计算机 A 上的进程,调用另外一台计算机 B 上的进程的方法。其中A 上面的调用进程被挂起,而 B 上面的被调用进程开始执行对应方法,并将结果返回给 A,计算机 A 接收到返回值后,调用进程继续执行。
发起 RPC 的进程通过参数等方式将信息传送给被调用方,然后被调用方处理结束后,再通过返回值将信息传递给调用方。这一过程对于开发人员来说是透明的,开发人员一般也无须知道双方底层是如何进行消息通信和信息传递的,这样可以让业务开发人员更专注于业务开发,而非底层细节。
RPC 让程序之间的远程过程调用具有与本地调用类似的形式。比如说某个程序需要读取某个文件的数据,开发人员会在代码中执行 read 系统调用来获取数据。
当 read 实际是本地调用时,read 函数由链接器从依赖库中提取出来,接着链接器会将它链接到该程序中。虽然 read 中执行了特殊的系统调用,但它本身依然是通过将参数压入堆栈的常规方式调用的,调用方并不知道 read 函数的具体实现和行为。
当 read 实际是一个远程过程时(比如调用远程文件服务器提供的方法),调用方程序中需要引入 read 的接口定义,称为客户端存根(client-stub)。远程过程 read 的客户端存根与本地方法的 read 函数类似,都执行了本地函数调用。不同的是它底层实现上不是进行操作系统调用读取本地文件来提供数据,而是将参数打包成网络消息,并将此网络消息发送到远程服务器,交由远程服务执行对应的方法,在发送完调用请求后,客户端存根随即阻塞,直到收到服务器发回的响应消息为止。
下图展示了远程方法调用过程中的客户端和服务端各个阶段的操作。

RPC 示意图
当客户端发送请求的网络消息到达服务器时,服务器上的网络服务将其传递给服务器存根(server-stub)。服务器存根与客户端存根一一对应,是远程方法在服务端的体现,用来将网络请求传递来的数据转换为本地过程调用。服务器存根一般处于阻塞状态,等待消息输入。
当服务器存根收到网络消息后,服务器将方法参数从网络消息中提取出来,然后以常规方式调用服务器上对应的实现过程。从实现过程角度看,就好像是由客户端直接调用一样,参数和返回地址都位于调用堆栈中,一切都很正常。实现过程执行完相应的操作,随后用得到的结果设置到堆栈中的返回值,并根据返回地址执行方法结束操作。以 read 为例,实现过程读取本地文件数据后,将其填充到 read 函数返回值所指向的缓冲区。
read 过程调用完后,实现过程将控制权转移给服务器存根,它将结果(缓冲区的数据)打包为网络消息,最后通过网络响应将结果返回给客户端。网络响应发送结束后,服务器存根会再次进入阻塞状态,等待下一个输入的请求。
客户端接收到网络消息后,客户操作系统会将该消息转发给对应的客户端存根,随后解除对客户进程的阻塞。客户端存根从阻塞状态恢复过来,将接收到的网络消息转换为调用结果,并将结果复制到客户端调用堆栈的返回结果中。当调用者在远程方法调用 read 执行完毕后重新获得控制权时,它唯一知道的是 read 返回值已经包含了所需的数据,但并不知道该 read 操作到底是在本地操作系统读取的文件数据,还是通过远程过程调用远端服务读取文件数据。
总结下RPC执行步骤:
1. 调用客户端句柄,执行传递参数。
2. 调用本地系统内核发送网络消息。
3. 消息传递到远程主机,就是被调用的服务端。
4. 服务端句柄得到消息并解析消息。
5. 服务端执行被调用方法,并将执行完毕的结果返回给服务器句柄。
6. 服务器句柄返回结果,并调用远程系统内核。
7. 消息经过网络传递给客户端。
8. 客户端接受数据。
RPC框架的组成
一个完整的 RPC 框架包含了服务注册发现、负载、容错、序列化、协议编码和网络传输等组件。不同的 RPC 框架包含的组件可能会有所不同,但是一定都包含 RPC 协议相关的组件,RPC 协议包括序列化、协议编解码器和网络传输栈,如下图所示:

RPC 协议一般分为公有协议和私有协议。例如,HTTP、SMPP、WebService
等都是公有协议。如果是某个公司或者组织内部自定义、自己使用的,没有被国际标准化组织接纳和认可的协议,往往划为私有协议,例如 Thrift 协议和蚂蚁金服的 Bolt 协议。
分布式架构所需要的企业内部通信模块,往往采用私有协议来设计和研发。相较公有协议,私有协议虽然有很多弊端,比如在通用性上、公网传输的能力上,但是高度定制化的私有协议可以最大限度地降低成本,提升性能,提高灵活性与效率。定制私有协议,可以有效地利用协议里的各个字段,灵活满足各种通信功能需求,比如:CRC 校验、Server Fail-Fast 机制和自定义序列化器。
在协议设计上,你还需要考虑以下三个关键问题:
1. 协议包括的必要字段与主要业务负载字段。协议里设计的每个字段都应该被使用到,避免无效字段。
2. 通信功能特性的支持。比如,CRC 校验、安全校验、数据压缩机制等。
3. 协议的升级机制。毕竟是私有协议,没有长期的验证,字段新增或者修改,是有可能发生的,因此升级机制是必须考虑的。
RPC和HTTP区别
RPC 和 HTTP都是微服务间通信较为常用的方案之一,其实RPC 和 HTTP 并不完全是同一个层次的概念,它们之间还是有所区别的。
1. RPC 是远程过程调用,其调用协议通常包括序列化协议和传输协议。序列化协议有基于纯文本的 XML 和 JSON、二进制编码的Protobuf和Hessian。传输协议是指其底层网络传输所使用的协议,比如 TCP、HTTP。
2. 可以看出HTTP是RPC的传输协议的一个可选方案,比如说 gRPC 的网络传输协议就是 HTTP。HTTP 既可以和 RPC 一样作为服务间通信的解决方案,也可以作为 RPC 中通信层的传输协议(此时与之对比的是 TCP 协议)。
常见的 RPC 框架
目前流行的开源 RPC 框架还是比较多的,有阿里巴巴的
Dubbo、Google 的 gRPC、Facebook 的 Thrift 和
Twitter 的 Finagle 等。
1. Go RPC:Go 语言原生支持的 RPC 远程调用机制,简单便捷。
2. gRPC:Google 发布的开源 RPC 框架,是基于 HTTP 2.0 协议的,并支持众多常见的编程语言,它提供了强大的流式调用能力,目前已经成为最主流的 RPC 框架之一。
3. Thrift:Facebook 的开源 RPC 框架,主要是一个跨语言的服务开发框架,作为老牌开源 RPC 协议,以其高性能和稳定性成为众多开源项目提供数据的方案选项。
gRPC入门学习之旅(一)的更多相关文章
- 180分钟的python学习之旅
最近在很多地方都可以看到Python的身影,尤其在人工智能等科学领域,其丰富的科学计算等方面类库无比强大.很多身边的哥们也提到Python非常的简洁方便,比如用Django搭建一个见得网站只需要半天时 ...
- 我的Android学习之旅(转)
去年大概在七月份的时候误打误撞接触了一阵子Android,之后由于工作时间比较忙,无暇顾及,九月份的时候自己空闲的时间比较多,公司相对来说加班情况没以前严重.开启了个人的Android学习之旅,初衷是 ...
- Java学习之旅开篇:运行机制及环境搭建
在写这篇博客之前,我想对自己进行简单概括:我从事软件开发工作已经三年多了,并且一直在从事.NET相关项目的开发.为什么突然间想学习Java呢?有以下几个原因: 1. 开发程序三年多来,已经对.NET相 ...
- AngularJS学习之旅
开篇 最近由于项目上可能需要用到AngularJS,公司将技术学习.调研的任务安排了下来,因此开始了我的AngularJS学习之路. 在这之前没写过技术博客,主要是由于太懒,另外自愧文笔不好,因此一直 ...
- asp.net+mvc+easyui+sqlite 简单用户系统学习之旅—— 摘要
首次接触asp.net开发,希望把自己的学习之旅写下来,一方面做个知识归纳技术总结,另一方面开放到博客中,和大家一起交流学习! asp.net是目前流行的web开发技术之一,是微软旗下开发的基于.ne ...
- hadoop学习之旅1
大数据介绍 大数据本质也是数据,但是又有了新的特征,包括数据来源广.数据格式多样化(结构化数据.非结构化数据.Excel文件.文本文件等).数据量大(最少也是TB级别的.甚至可能是PB级别).数据增长 ...
- Go 中的 gRPC 入门详解
目录 Go GRPC 入门 1,安装包 2,gRPC 服务端 3,gRPC 客户端 4,编译运行 5,其它 GRPC Protobuf buffer 字段类型 字段规则 Protobuf gRPC 四 ...
- WCF学习之旅—第三个示例之四(三十)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) WCF学习之旅—第三个示例之三(二十九) ...
- vue入门学习(基础篇)
vue入门学习总结: vue的一个组件包括三部分:template.style.script. vue的数据在data中定义使用. 数据渲染指令:v-text.v-html.{{}}. 隐藏未编译的标 ...
- Hadoop学习之旅二:HDFS
本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...
随机推荐
- 紧跟潮流,抓住趋势,跟上全民AI的节奏,开源IM项目OpenIM产品介绍,为AIGC贡献力量
开源价值 高度自主.安全可控.开放自由,私有化部署,一切皆可控 透明度和可信度:开源软件的源代码是公开的,任何人都可以查看和检查代码,从而增强了软件的透明度和可信度.用户可以了解软件的内部结构和运作方 ...
- 年末将至,Java 开发者必须了解的 16 个Java 顶级开源项目!
年末将至,值得你关注的16个Java 开源项目! 本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb/JavaGuide ([Java学习+面试 ...
- 【Java】引用传递?值传递?
引用传递和值传递,从上学那会儿就开始强调的概念,不管你是计算机相关专业还是自学Java,一定听过这么一句话: 方法调用参数如果是对象,那就是引用传递,如果是基本数据类型,就是值传递. 比如:funct ...
- PostFix+Dovecot 部署邮件系统
Postfix 是一种电子邮件服务器是一个开放源代码的软件. Postfix 是MTA邮件传输代理软件.是sendmail提供替代品的一个尝试,在Internet世界中,大部分的电子邮件都是通过sen ...
- 记录一下配置mysql高可用(MHA)的过程及踩到的坑
记录一下搭建MHA主从的完整过程,同时也把自己部署过程中遇到的坑写进来 参考链接: https://blog.csdn.net/m0_49526543/article/details/10948365 ...
- Redis主从配置、数据持久化、集群
发布订阅 ## subscribe 订阅一个或者多个频道 ## publish 给指定的频道发送消息 ## psubscribe 订阅指定模式的频道,*代表所有 ## pubsub channels ...
- conditional_t和enable_if_t的实现
conditional_t和enable_if_t是元编程里面很相似却有有着一定区别的模板.形如conditional_t<_Cond, _If, _Else>是指如果_Cond表达式 ...
- 【Unity3D】摇杆
1 需求实现 1)需求实现 鼠标拖拽摇杆球控制坦克移动: 上下左右按键也可以控制坦克移动,并且摇杆球也同步移动: 鼠标右键滑动,控制坦克转向: 相机在玩家后上方的位置,始终跟随玩家,朝玩家正前方看 ...
- oracle exp/imp命令使用parfile实现参数文件调用
优先使用数据泵(expdp/impdp)方式,更高效,问题少. 关于exp/imp工具的使用请参考我的另一篇文章: https://blog.csdn.net/IndexMan/article/det ...
- kubernetes(k8s)大白学习01-kubernetes是什么?有什么用?
kubernetes(k8s)大白基础学习-kubernetes是什么? 一.认识 Docker Docker 是什么 先来看看 Docker 的图标: 一条鲸鱼背上驮着四方形块的物品,就像一条海运船 ...