前言
上一篇已经讲到服务提供者 注册完之后,会往zk节点 /dubbo/接口名/configurator节点注册监听事件,当该节点发生变化时,会调用NotifyListener监听器实例的notify方法来调用重载配置信息的逻辑。
1. 注册事件后,自动触发调用notify()
在注册完对/dubbo/接口名/configurator节点的监听事件
后,手动的调用一次notify()方法
首先利用这个方法往urls一个基于原url生成empty的协议
image把传入的url改成empty协议头
image如果注册监听事件之后返回的configurator节点下已有数据,也会获取到放在这个urls里面
image image每一个configurator的元素都会返回一个url放入到urls中
image
进入notify()
image image如果匹配的话,放到一个局部的map。
category : List<匹配的url>
这时候肯定是匹配的,因为新生成的empty的url就是根据原url改了protocol得来的
image
又有一个缓存容器
ConcurrentMap<URL, Map<String, List<URL>>> notified :
{url : {"configurator" : List<Url>}}
image
一开始肯定根据url拿不到,直接新建,并把result放到复制到url的map中
image放完之后是这样的
image把这几个configurator的协议写到本地文件中
image调用 dubbo监听器的方法
imagelistener.notify(categoryList) 核心
1.根据匹配到的url 获取Configurator对象
image这里有一个重点,如果传入的url中有一个empty协议,就会清空list,返回空的configurators list
image否则对应每一个非empty url的生成一个Configurator对象
image2. 获取原始的的dubbo协议url
image3. 通过configurators对象对原来的dubbo协议url进行修改,覆盖,生成新的url,由于这里自动调用notify,传入的empty协议,并不会去对原来的url进行修改
image image2. 监听override协议,生成新的url
测试代码
利用dubbo的Registry api往configurator节点下写入override协议
@RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试
@ContextConfiguration(classes = {AnnoBean.class})
public class SpiTest {
@Test
public void testOverride(){
RegistryFactory registryFactory =ExtensionLoader.getExtensionLoader(Reistr yFactory.class).getAdaptiveExtenson();
Registry registry =registryFactory.getRegistry(URL.valuef("z ookeeper://maomaoyu.xyz:2181"));
registry.register(URL.valueOf("overrie://0 .0.0.0/com.lb.dubbo_api.service.serService ?category=configurators&dynmic=false&appli cation=foo&timeout=200"));
}
}
测试代码跑完,configurator节点出现我们刚写入的override协议
image这个时候,之前注册的事件监听器就会被调到.
image走的代码跟第一点讲的他自动调的那一次监听器一样的流程
image image同样的再调到监听器的notify方法,只不过这次由于没有empty协议,获取到的configurators有值了
imageconfigurators有值之后,会根据这个列表对原来的url进行覆盖,生成新的newUrl
url被override url覆盖
image这里会有一个比较重要的判断
如果是当前监听到配置信息变更的服务实例的角色为消费者,那么会进行本机地址和override协议指定的地址进行判断,如果相等才会更新当前实例的配置信息。因为这个事件监听,所有该服务接口的消费者和生产者都会注册,都会接到变更的通知。
而生产者则不用判断本机地址和override协议指定的地址是否一直
image image==这就说明,更新配置信息 如果是对消费端的话,是针对ip更新某一台服务实例,如果是针对生产端的话,是更新所有生产方的配置信息==
生成新的url
image对其他的属性进行覆盖
image2. 根据生成的新的url,重新创建export对象
判断新url是否和原来的url是否相同
image不相同,根据invoker对象和新url创建新的Exporter对象
image接下来的代码和服务发布的时候,创建export对象是一样的
网友评论