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

一、什么是 RPC?

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

功能:

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

二、RPC 通信流程

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

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

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

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

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

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

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

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

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

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

三、设计协议

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

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

可以扩展的协议:

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

四、序列化

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

常用的序列化

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

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

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

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我理解了你的问题,并且会尽力回答。首先,我们需要了解一些背景知识。 在Hadoop分布式文件系统中,Namenode是整个系统的核心组件之一。它负责管理文件系统的元数据,如目录结构、文件属性和数据块列表等。此外,Namenode还负责维护集群的状态,包括数据块的存储位置、节点的健康状态等。 为了实现Namenode的功能,我们需要编写一个Java类,并实现NamenodeService接口中定义的JSON-RPC方法。这个类需要维护文件系统的元数据,并提供一系列方法来处理文件系统的操作,如创建文件、删除文件、重命名文件等。 下面是一个简单的示例代码,用于说明Namenode类的基本结构和实现方法: ```java public class Namenode implements NamenodeService { private Map<String, FileStatus> metadata; public Namenode() { metadata = new HashMap<>(); } // 实现JSON-RPC方法 public String create(String path, boolean overwrite) { // 处理创建文件的逻辑 return "success"; } public String delete(String path, boolean recursive) { // 处理删除文件的逻辑 return "success"; } public String rename(String src, String dst) { // 处理重命名文件的逻辑 return "success"; } // 其他方法 public FileStatus getFileStatus(String path) { // 返回指定文件的元数据 return metadata.get(path); } public boolean exists(String path) { // 判断指定文件是否存在 return metadata.containsKey(path); } public void addFileStatus(String path, FileStatus status) { // 添加指定文件的元数据 metadata.put(path, status); } // 其他方法省略 } ``` 在上面的代码中,Namenode类实现了NamenodeService接口中定义的JSON-RPC方法,并维护了文件系统的元数据。这个类提供了一系列方法来处理文件系统的操作,如创建文件、删除文件、重命名文件等。 需要注意的是,这个示例代码仅用于说明Namenode类的基本结构和实现方法,并没有考虑分布式文件系统的复杂性和安全性问题。在实际开发中,需要更加细致地考虑这些问题,并确保系统的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值