RPC 开发系列一:RPC 基本介绍

一、什么是 RPC?

        RPC 的全称是 Remote Procedure Call,即远程过程调用。

功能:

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

二、RPC 通信流程

        发起调用请求的那一方叫做调用方,被调用的一方叫做服务提供方。RPC 一般默认采用 TCP 来传输。我们常用的 HTTP 协议也是建立在 TCP 之上的。

RPC 的通讯流程:序列化 --->  网络传输 ---> 反序列化

        数据格式的约定内容叫做“协议”。大多数的协议会分成两部分,分别是数据头和消息体。数据头一般用于身份识别,包括协议标识、数据大小、请求类型、序列化类型等信息;消息体主要是请求的业务参数信息和扩展属性等。

        更上一层楼,其中简化 API,屏蔽掉 RPC 细节,让使用方只需要关注业务接口也是关键(可以参考AOP 技术)。

        AOP 技术:采用动态代理的技术,通过字节码增强对方法进行拦截增强,以便于增加需要的额外处理逻辑。

RPC 开发系列一:RPC 基本介绍_第1张图片

  RPC 的通讯就变成流程:动态代理 ---> 序列化 --->  网络传输 ---> 反序列化 ----> 执行          

        RPC 是解决应用间通信的一种方式,而无论是在一个大型的分布式应用系统还是中小型系统中,应用架构最终都会从“单体”演进成“微服务化”,整个应用系统会被拆分为多个不同功能的应用,并将它们部署在不同的服务器中,而应用之间会通过 RPC 进行通信,可以说 RPC 对应的是整个分布式应用系统,就像是“经络”一样的存在

        RPC 框架能够帮助我们解决系统拆分后的通信问题,并且能让我们像调用本地一样去调用远程方法。利用 RPC 我们不仅可以很方便地将应用架构从“单体”演进成“微服务化”,而且还能解决实际开发过程中的效率低下、系统耦合等问题,这样可以使得我们的系统架构整体清晰、健壮,应用可运维度增强。当然 RPC 不仅可以用来解决通信问题,它还被用在了很多其他场景,比如:发 MQ、分布式缓存、数据库等。

RPC 开发系列一:RPC 基本介绍_第2张图片

        上面的图不能表达所有的情况,但是能说明 RPC 的框架。

        一句话概括: RPC 是我们最“熟悉的陌生人”。

三、设计协议

         这样整个协议就会拆分成两部分:协议头和协议体。

  1. 协议头:协议长度、序列化方式,还会放一些像协议标示、消息 ID、消息类型这样的参数。
  2. 协议体:接口方法、请求的业务参数值和一些扩展属性。

可以扩展的协议:

        整体协议就变成了三部分内容:固定部分、协议头内容、协议体内容,前两部分我们还是可以统称为“协议头”

RPC 开发系列一:RPC 基本介绍_第3张图片

四、序列化

        序列化就是将对象转换成二进制数据的过程,而反序列就是反过来将二进制转换为对象的过程。

常用的序列化

  • JDK 原生序列化
  • JSON
  • Hessian
  • Protobuf

如何选择序列化?

        首先可能想到的是性能和效率,还有空间开销,也就是序列化之后的二进制数据的体积大小。序列化协议的通用性和兼容性,序列化后的字节数据体积越小,网络传输的数据量就越小,传输数据的速度也就越快。 

 RPC 框架的过程中,构造入参、返回值对象,注意的问题:

  • 对象要尽量简单,没有太多的依赖关系,属性不要太多,尽量高内聚;
  • 入参对象与返回值对象体积不要太大,更不要传太大的集合;
  • 尽量使用简单的、常用的、开发语言原生的对象,尤其是集合类;
  • 对象不要有复杂的继承关系,最好不要有父子类的情况。

五、网络通讯

网络 IO 模型:

  • 同步阻塞 IO(BIO)
  • 同步非阻塞 IO(NIO)
  • IO 多路复用
  • 异步非阻塞 IO(AIO)

最常用的就是同步阻塞 IO 和 IO 多路复用。

同步阻塞 IO:

        应用进程发起 IO 系统调用后,应用进程被阻塞,转到内核空间处理。之后,内核开始等待数据,等待到数据之后,再将内核中的数据拷贝到用户内存中,整个 IO 处理完毕后返回进程。最后应用的进程解除阻塞状态,运行业务逻辑。这里我们可以看到,系统内核处理 IO 操作分为两个阶段——等待数据和拷贝数据。

IO 多路复用:

         多路就是指多个通道,也就是多个网络连接的 IO,而复用就是指多个通道复用在一个复用器上。当用户进程调用了 select,那么整个进程会被阻塞。同时,内核会“监视”所有的 socket,当任何一个 socket 中的数据准备好了,select 就会返回。这个时候用户进程再调用 read 操作,将数据从内核中拷贝到用户进程。

什么是零拷贝?

        所谓的零拷贝,就是取消用户空间与内核空间之间的数据拷贝操作。零拷贝有两种解决方式,分别是 mmap+write 方式和 sendfile 方式,mmap+write 方式的核心原理是通过虚拟内存来解决的。

五、动态代理

Spring AOP:

        就是采用动态代理技术,通过对字节码进行增强,在方法调用的时候进行拦截,以便于在方法调用前后,增加我们需要的额外处理逻辑 。

参考:https://www.cnblogs.com/joy99/p/10941543.html

        RPC 会自动给接口生成一个代理类,当我们在项目中注入接口的时候,运行过程中实际绑定的是这个接口生成的代理类。这样在接口方法被调用的时候,它实际上是被生成代理类拦截到了,这样我们就可以在生成的代理类里面,加入远程调用逻辑。

RPC 开发系列一:RPC 基本介绍_第4张图片

动态代理可以从这样三个角度去考虑:

  • 生成的字节码越小,运行所占资源就越小。
  • 以每次调用接口方法的时候,都执行生成的代理类,这时生成的代理类的执行效率就需要很高效。
  • 选择一个使用起来很方便的代理类框架:API 设计是否好理解、社区活跃度、还有就是依赖复杂度等等。

你可能感兴趣的:(RPC,原理,rpc,动态代理)