RPC 框架分层设计 | 青训营笔记

92 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天,今天学习的课程是RPC 框架分层设计

1.什么是 RPC?

RPC 的全称是 Remote Procedure Call,即远程过程调用。简单解读字面上的意思,远程肯定是指要跨机器而非本机,所以需要用到网络编程才能实现,但是不是只要通过网络通信访问到另一台机器的应用程序,就可以称之为 RPC 调用了?显然并不够。

我理解的 RPC 是帮助我们屏蔽网络编程细节,实现调用远程方法就跟调用本地(同一个项目中的方法)一样的体验,我们不需要因为这个方法是远程调用就需要编写很多与业务无关的代码。

所以我认为,RPC 的作用就是体现在这样两个方面:

1.拼比底层网络通信的复杂性,让我们感觉就是调用项目内的方法。

2.比起http请求 通信的效率 带宽利用率更高 也就是在报文中 有效数据的占比更高

屏蔽远程调用跟本地调用的区别,让我们感觉就是调用项目内的方法; 隐藏底层网络通信的复杂性,让我们更专注于业务逻辑。

2.RPC 框架的结构

以下是dubbo的架构图

image.png

一个最简单的 RPC 框架分成三个部分:注册中心、服务端、客户端。以下是一个最简单的结构流程图。

组成部分:

注册中心:用于注册和获取服务。 服务端:指提供服务的一方,也叫服务提供方 Provider 客户端:指调用服务的一方,也叫服务消费者 Consumer 流程:

服务端把服务信息注册到注册中心,通常包含服务端地址、接口类和方法 客户端从注册中心获取对应服务的信息 客户端根据服务的信息,通过网络调用到服务端的接口

3.RPC 框架的设计

上面的流程

  1. 服务端以什么形式注册到注册中心?
  2. 客户端是怎么做到像调用接口一样调用服务?
  3. 调用服务的网络协议是怎样的?

一个基本的 RPC 框架,需要包含以下部分:

  1. 注册中心:注册中心负责服务信息的注册与查找。服务端在启动的时候,扫描所有的服务,然后将自己的服务地址和服务名注册到注册中心。客户端在调用服务之前,通过注册中心查找到服务的地址,就可以通过服务的地址调用到服务啦。常见的注册中心有 ZookeeperEureka 等。
  2. 动态代理:客户端调用接口,需要框架能自己根据接口去远程调用服务,这一步是用户无感知的。这样一来,就需要使用到动态代理,用户调用接口,实际上是在调用动态生成的代理类。常见的动态代理有:JDK ProxyCGLibJavassist 等。
  3. 网络传输:RPC 远程调用实际上就是网络传输,所以网络传输是 RPC 框架中必不可少的部分。网络框架有 Java NIONetty 框架等。
  4. 自定义协议:网络传输需要制定好协议,一个良好的协议能提高传输的效率。
  5. 序列化:网络传输肯定会涉及到序列化,常见的序列化有JsonProtostuffKyro 等。
  6. 负载均衡:当请求调用量大的时候,需要增加服务端的数量,一旦增加,就会涉及到符合选择服务的问题,这就是负载均衡。常见的负载均衡策略有:轮询、随机、加权轮询、加权随机、一致性哈希等等。
  7. 集群容错:当请求服务异常的时候,我们是应该直接报错呢?还是重试?还是请求其他服务?这个就是集群容错策略啦。
  8. SPI机制 作为一个框架,支持插件化的必要功能
  9. 支持rpc 同步调用和异步调用