rpc的实现基础(《RPC实战与核心原理》学习笔记Day6)
07 | 架构设计:设计一个灵活的RPC框架
RPC就是把拦截到的方法参数 ,转成可以在网络中传输的二进制 ,并保证在服务提供方能正确地还原出语义 ,最终实现像调用本地一样地调用远程的目的 。
RPC的本质是一个远程调用 ,需要通过网络来传输数据 ,我们一般采用TCP协议作为数据通信协议 ,为了屏蔽网络传输的复杂性 ,我们需要封装一个独立的数据传输模块来收发二进制数据 ,这个模块被称为传输模块 。我们在调用方法时 ,方法的出入参数都是对象数据,我们需要将对象转换成二进制 ,即进行序列化操作 ,同时,我们还需要在方法调用参数的二进制数据后面增加“断句 ”符号来分隔出不同的请求 ,这个过程被称为协议封装。
传输模块和协议封装都是为了保证数据在网络中可以正确传输 ,我们将这两个模块放在一起,称为协议模块 。
我们还可以在协议模块中添加压缩功能 ,在方法调用参数或者返回值的二进制数据大于某个阈值时 ,我们使用压缩框架对数据进行无损压缩 ,然后再另外一段使用同样的压缩机制进行解压处理 ,保证数据可以还原 。
传输模块和协议模块是RPC中最基础的功能 ,它们使得对象可以正确的传输到服务提供方 。但是为了让这两个模块可以同时工作 ,我们还需要手写一些粘合代码 ,这些代码对于RPC框架的使用者来说是没有意义的 ,属于重复工作 ,我们将这些事情进行封装处理,形成RPC调用的入口 ,一般称为Bootstrap模块 。
什么是 ”服务发现“?
针对同一个接口有多个服务提供者 ,但这多个服务提供者对于我们的调用方来说是透明的,所以在RPC里面我们还需要给调用方找到所有的服务提供方 ,并需要在RPC里面维护好接口和服务提供者地址间的关系 ,这样调用方在发起请求时才能快速找到对应的接收地址 。
一个划分为四层的RPC基础架构的示意图如下 。
上面的框架有什么问题吗?最主要的问题就是扩展性不高,当我们有需求变更时 ,很容易需要大范围调整框架 。
我们可以尝试使用插件化架构的方法论来优化我们的RPC架构 。
我们怎么在RPC框架里面支持插件化架构?
我们可以将每个功能点抽象成一个接口 ,将这个接口作为插件的契约 ,然后把这个功能的接口与功能的实现分离 ,并提供接口的默认实现 。
加入插件功能后 ,RPC框架就包含了两大核心体系:核心功能体系和插件体系 ,示意图如下。
彩蛋 - Java SPI
什么是Java SPI?
SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制 ,可以用来扩展框架和替换组件 ,它的核心思想是解耦 。
例如针对DB驱动程序 ,java.sql.Driver接口定义了相关规范,不同的厂家会针对这一规范提供不同的实现 ,例如MySQL和PostgreSQL会提供不同的实现给用户 。
SPI和API有什么区别?
API是调用并用于实现目标的类 、接口 、方法等的描述。 SPI是扩展和实现类似目标的类 、接口和方法等的描述 。SPI的使用流程是怎样的?
相关组织或者公司发布接口规范定义 。 第三方根据接口提供具体实现。 开发者在程序中针对SPI进行配置并使用 。JDK提供的SPI有哪些不足?
不能按需加载 ,需要遍历所有的实现,并实例化 ,然后才能在循环中找到我们需要的实现 。 获取某个实现类的方式不够灵活 。 多个并发多线程使用ServiceLoader类的实例是不安全的 。创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!