侧边栏壁纸
  • 累计撰写 247 篇文章
  • 累计创建 16 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

RPC 框架是如何实现 RPC 通信的

kaixindeken
2021-04-23 / 0 评论 / 0 点赞 / 136 阅读 / 1,675 字

微服务解决单体应用瓶颈的同时也引入了新的问题,即远程方法调用过程中协议约定、服务发现以及网络传输的复杂度增加,必须要解决这些问题才能保证远程方法调用的可靠性,在工程实践中,我们通常使用一些优秀的开源 RPC 框架来处理这些底层问题(如 Spring Cloud、Dubbo、gRRC、Thrift、Hprose 等),作为一般开发者,只需要基于这些框架专注上层服务实现即可,但是作为一个有追求的开发者,最好能够理解 RPC 框架底层的实现,这样才能更好的使用这些框架。

现有的 RPC 框架都是基于 Andrew D. Birrell 和 Bruce Jay Nelson 的论文实现的:Implementing Remote Procedure Calls ,该论文定义了 RPC 的调用标准,这篇论文对于英文不好的人啃起来有些吃力(这里有一篇中文译文,感兴趣的可以看看),我们把它简化为下面的模型来介绍:

1.jpeg

当客户端应用(服务消费方)想发起一个远程调用时,实际是通过本地调用客户端的 Stub,该 Stub 负责将调用的接口、方法和参数,通过约定的协议规范进行编码,并通过本地的 RPCRuntime(RPC 通信包) 进行传输,最终将调用网络包发送到服务器。

服务器端的 RPCRuntime 收到请求后,交给服务提供方 Stub 进行解码,然后调用服务端对应的方法,方法执行后返回结果,服务提供方 Stub 将返回的结果编码后,再发送给客户端,客户端的 RPCRuntime 收到结果,发给调用方 Stub 解码得到结果,返回给客户端。

至此,一个完整的 RPC 调用就完成了。这里面分了三个层次,对于用户层和服务端,都像是本地调用一样,专注于业务逻辑的处理就可以了,实际上,我们在进行微服务开发时,基本上也就是专注在这两块,即服务端如何提供服务和客户端如何消费服务。底层的 Stub 处理双方约定好的语法、语义、封装和解封装(解决了协议约定问题),RPCRuntime 则主要处理高性能的传输,以及网络的错误和异常(解决了网络传输问题)。

但还有一个问题,就是服务发现问题,即客户端调用远程服务时,如何得知要去哪个服务器调用呢?在这篇论文中,实现的方案是通过一个分布式数据库 Grapevine 来绑定服务名与对应的服务提供方地址,当服务端提供新的服务时,需要将其「注册」到 Grapevine,然后客户端 RPCRuntime 在发起远程调用时可以从 Grapevine 中查询到服务名对应的服务端地址,进而发起网络请求:

1.jpeg

Grapevine 即对应着后面微服务分享中要介绍的 RPC 框架中的「注册中心」,目前比较主流的注册中心实现方案有 zookeeper、eureka、consul、etcd 等。

Sun 公司是第一个提供商业化 RPC 库和 RPC 编译器的公司,最早的 RPC 实现就是该公司提供的 ONC RPC(Open Network Computing Remote Procedure Call,开放网络计算远程方法调用),由于该 RPC 实现用在 Sun 系统中,所以也叫 Sun RPC。我们比较熟悉的 NFS(Network File System,网络文件系统) 协议就是基于 ONC RPC 实现的。

0

评论区