当前位置: 首页 > news >正文

高阶面试-dubbo的学习

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

SPI机制

SPI,service provider interface,服务发现机制,其实就是把接口实现类的全限定名配置在文件里面,然后通过加载器ServiceLoader去读取配置加载实现类,比如说数据库驱动,我们把mysql的jar包放到项目的lib后,DriverManager.getConnection() 就获取到mysql的连接了呢?

其实 DriverManager的静态代码块里面有个loadInitialDrivers方法,调用的ServiceLoader.load(Driver.class) 然后迭代遍历hasNext方法再调用hasNextService,里面指定从META-INF/service目录下找接口名的文件,里面写的java.sql.Driver的mysql实现的全限定名com.mysql.cj.jdbc.Driver

在这里插入图片描述

参考java,dubbo也实现自己的,并进行增强,java的只能循环遍历,dubbo搞的是k=v的形式,可以按需查找

dubbo写了个ExtensionLoader,里面有几个全局映射map,Class和ExtensionLoader的映射、Class和对应实例对象的映射,根据key找到持有value的holder,然后根据holder获取实例,通过双检锁保证实例唯一。

那dubbo除了生成实例外,还有什么增强吗?

有的,dubbo也有IOC,有个injectExtension方法,是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中。

那除了IOC外,还有什么增强吗?

哈哈,其实也有AOP,装饰器模式,有Wrapper类,使用Wrapper类包装原始的扩展点实例。在原始扩展点实现前后插入其他逻辑,实现AOP功能。也是在createExtension方法里面,在IOC之后,做AOP,判断是否有wrapperClass,有的话,遍历,将当前实例包装到wrapper中,通过构造注入,在wrapper中注入依赖,实现增强,还能层层套,如果多个wrapper,由于instance已经变成第一个wrapper包装后的instance,会在外层再包装
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));

除了AOP还有什么增强吗?
自适应,我们一般扩展点的想法是什么,比如在yaml中配置protol是dubbo,然后呢,框架启动的时候去加载对应的扩展点,那假如我们不想框架启动阶段就加载,而是希望拓展方法被调用的时候,根据运行时的参数进行加载,也就是根据参数动态加载实现类,那要怎么实现呢?
创建接口的自适应实例getAdaptiveExtensionClass()是核心
首先会使用一个StringBuilder来生成自适应类的Java源码,然后再将源码编译成Java的字节码,加载到JVM中,目前是通过javassist实现的。

dubbo的服务暴露机制和源码实现

服务暴露,其实核心就是两点:

  • 开启服务
  • 服务注册

怎么实现呢?
先要了解dubbo怎么传递注册信息等配置信息的,通过url,还挺巧妙的
采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息

dubbo的ServiceBean实现了ApplicationListener,方法onApplicationEvent在容器完成初始化后,调用export导出服务实现服务暴露。核心是doExportUrlsFor1Protocol方法,先各种装配配置参数信息,组装url,然后如果是远程调用,通过代理ProxyFactory转换为Invoker,Dubbo 默认的 ProxyFactory 实现类是 JavassistProxyFactory。RegistryProtocol.export。里面先protocol.export,根据协议如dubbo导出,把Invoker转换为Exporter,这里面会开启服务openServer。
服务注册呢?先根据URL加载 Registry 实现类,然后调register方法向注册中心注册服务。根据SPI机制找到 ZookeeperRegistry extends FailbackRegistry extends AbstractRegistry,register方法在 FailbackRegistry 中,真正执行注册是在ZookeeperRegistry中的doRegister方法里。

dubbo的服务发现机制和源码分析

和provider对应,有个ReferenceConfig,核心也是两点:

  • 先从注册中心获取服务信息
  • 创建客户端

入口在哪里呢?ReferenceBean实现了FactoryBean,真正被注入到容器中的是由getObject方法返回的对象。里面init方法主要用于处理配置,以及调用 createProxy 生成代理类。createProxy一个是构建Invoker实例。调用 RegistryProtocol 的 refer 构建 Invoker 实例。然后getProxy根据Invoker 真正生成代理,实际是子类 JavassistProxyFactory 实现 getProxy方法。

其实注册和创建客户端都是在 RegistryProtocol 的 refer 方法中实现的。先是registry.register注册到zk,然后directory.subscribe订阅,会调ZookeeperRegistry#doSubscribe,最终是调RegistryDirectory#refreshOverrideAndInvoker将providers对应url封装成 invoker,核心是new DubboInvoker,里面的getClients去initClient初始化新的客户端,内部调Exchanger调NettyClient的doOpen再doConnect打开并和对端建立连接,

dubbo的RPC协议

在这里插入图片描述

如图,包括header和body

  • 16bit 魔术 高位和低位,总共16bit,0xdabb
  • 1bit 请求响应标志 请求1 响应0
  • 1bit 是否需要往返 请求的时候有用,如果需要来自服务器的返回值,值为1
  • 1bit event事件,如心跳事件 值为1
  • 5bit 序列化ID,标识序列化类型,如fastjson是6
  • 8bit 响应状态码 20ok 30 client超时等
  • 64bit requestId唯一请求 long类型 8个字节
  • 32bit 消息体的data length,int类型 4个字节
  • body 序列化后的body

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • android 消除内部保存的数据
  • 【分布式系统】Filebeat+Kafka+ELK 的服务部署
  • centos 安装ffmpeg
  • 栈(Stack)与队列(Queue,Deque)
  • 亚信安全新一代终端安全TrustOne2024年重磅升级
  • U盘打不开的终极解决方案:原因剖析、恢复策略与预防之道
  • JavaSe系列二十七: Java正则表达式
  • Linux rpm和ssh损坏修复
  • 解析 pdfminer layout.py LAParams类及其应用实例
  • Redis 集群模式
  • 宝兰德参编金融智能体标准,深耕大模型场景化落地
  • ubuntu防火墙指定端口开放设置
  • c#获取本机的MAC地址(附源码)
  • Python学习笔记36:进阶篇(二十五)pygame的使用之事件监听控制切歌和暂停,继续播放
  • 黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录 Day4
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 2019.2.20 c++ 知识梳理
  • ES6语法详解(一)
  • gf框架之分页模块(五) - 自定义分页
  • Git的一些常用操作
  • HTTP 简介
  • Laravel核心解读--Facades
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Mysql数据库的条件查询语句
  • Python - 闭包Closure
  • python_bomb----数据类型总结
  • Python爬虫--- 1.3 BS4库的解析器
  • SpiderData 2019年2月16日 DApp数据排行榜
  • supervisor 永不挂掉的进程 安装以及使用
  • 大主子表关联的性能优化方法
  • 工程优化暨babel升级小记
  • 关于List、List?、ListObject的区别
  • 基于axios的vue插件,让http请求更简单
  • 类orAPI - 收藏集 - 掘金
  • 问题之ssh中Host key verification failed的解决
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 数据可视化之下发图实践
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​如何在iOS手机上查看应用日志
  • #FPGA(基础知识)
  • #数据结构 笔记三
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (5)STL算法之复制
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (分布式缓存)Redis哨兵
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (三)elasticsearch 源码之启动流程分析
  • (一) springboot详细介绍
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**