本篇内容主要讲解“Dubbo注册中心是怎么设计的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Dubbo注册中心是怎么设计的”吧!
关于源码和原理的分析,我们都需要找寻一个切入点,找到切入点的前提是你要知道注册中心的功能是什么,注册中心相信大家都不陌生,每一个通用的注册中心都需要提供两个基本的功能点:
-
服务提供者将自己暴露的服务向注册中心注册
-
服务消费者可以从注册中心获取自己所需要的服务
首先我们要确定Dubbo关于注册中心的源码包的位置:org.apache.dubbo.registry。下面我们看一下包的目录结构图:
上图红色框中的9个包对应Dubbo中9种注册中心的实现,从包的名称也可以看出具体的注册中心实现的方式。其中Dubbo官网推荐的注册中心方式的实现是基于ZooKeeper的注册中心。那么下面我们就分析以ZooKeeper为基础的注册中心在Dubbo中是如何实现的。
Dubbo注册中心设计
其实在我们在学习开源框架的过程中,除了学会他们的使用以外,还可以通过分析源码学习这些开源框架的设计,每一个开源框架的实现基本都是易扩展的,这种易扩展的特性都得益于优秀的设计模式。下面我们就先看一下Dubbo在注册中心实现上是怎样设计来支持各种各样的注册中心的。
SPI
SPI(Service Provider Interface)是Java提供的一种服务发现的机制。SPI通俗一点讲就是在运行期间使用一个具体的接口实现类来动态的替换接口。
Java中的具体实现很简单,只需要你定义一个接口,然后采用具体的实现类实现这个接口,然后在META-INFO/services建立一个以接口的全量限定名称命名的文件,该文件的内容是具体的接口实现类的全量限定名称。
Java中有一个java.util.ServiceLoader可以查找服务的具体实现。
Dubbo SPI
Dubbo并没有直接使用Java原生的SPI,而是重新实现了一套功能更强的SPI机制。Dubbo SPI的相关逻辑被封装在ExtensionLoader类中,具体分析请见官网。这里只简单讲解一下扩展类动态替换的基本流程。
-
首先需要获取ExtensionLoader实例(调用ExtensionLoader.getExtensionLoader(Class
type)),这里的type为接口类 -
通过ExtensionLoader实例调用getExtension(String name)方法来获取具体的实例(name是Dubbo中配置的扩展类的key值),该步骤首先从缓存中获取具体的扩展类实例,如果获取到则直接返回(此时说明扩展类实例曾经被加载过),如果没有则需要进行创建(调用createExtension(String name)方法)并且将其存放在缓存中(这一步中采用双重检测+锁的实现方式来避免并发问题,具体写法请自己看源码)
-
创建实例之前,我们首先要根据name找到对应的扩展类对应的具体实现类(getExtensionClasses().get(name)),要想找到具体的实现类,首先需要获取到应用中所有的扩展类的具体实现类(getExtensionClasses())
-
在获取之前,先查看type所代表的接口类上是否有@SPI注解,如果有则进行解析并且缓存默认的key(@SPI注解的value值),紧接着就是加载具体的扩展类的实现类,获取具体扩展类的实现类也是基于缓存获取的,如果发现能从缓存中获取到一个实现类的集合就直接返回,否则就需要加载应用中的所有扩展类的具体实现类并将其存入缓存中,key为文件中=前的部分,value为=后面代表的具体的Class
-
第二步传入的name值然后从Map中获取Class,如果获得的为空则抛出异常,否则就获取成功
-
在获取到具体的Class以后,首先验证缓存中是否已经缓存过该Class的具体对象,如果没有缓存则创建一个新的对象并进行缓存
-
在获取到具体扩展实现类的对象以后,需要利用反射进行赋值(调用injectExtension方法)注入依赖,这部分功能就需要依赖Dubbo IOC功能
Dubbo IOC
Dubbo首先会通过反射获取到所有的setter方法,然后通过ExtensionFactory获取到依赖对象,最后通过反射调用将依赖设置到目标对象中。在ExtensionLoader使用的ExtensionFactory是AdaptiveExtensionFactory,AdaptiveExtensionFactory内部维护了一个ExtensionFactory列表,用于存储其他类型的ExtensionFactory。Dubbo目前提供了两种ExtensionFactory,分别是SpiExtensionFactory和SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从Spring的IOC容器中获取所需的拓展。
到此,相信大家对“Dubbo注册中心是怎么设计的”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/223716.html