dubbo 2.6.2 服务暴露过程

dubbo 使用了自定义标签 namespace 是http://dubbo.apache.org/schema/dubbo

spring 使用自定义标签需要到classpath目录下META-INF目录添加spring.handlers 添加namespace解析器

所以找到了org.apache.dubbo.config.spring.schema.DubboNamespaceHandler

registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());

以上是注册每个标签的解析

所以服务暴露使用的是ServiceBean这个类(解析过程就不介绍了)

ServiceBean实现了spring的接口ApplicationListener 在容器刷新的时候会执行实现的方onApplicationEvent

服务就是在这方法里面暴露 然后就是大量的参数配置过程

export();-->doExport();-->doExportUrls();
List registryURLs = loadRegistries(true);//这儿获取的是配置的注册中心里面的对象如下:registry://localhost:2181/org.apache.dubbo.registry.RegistryService?application=sp1&dubbo=2.0.2&pid=14140®istry=zookeeper×tamp=1535640116290

这儿的protocols 是配置的暴露服务协议 有配置就是

for (ProtocolConfig protocolConfig : protocols) { doExportUrlsFor1Protocol(protocolConfig, registryURLs); }

doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List registryURLs)

然后获取本机ip和服务端口号 和注册配置参数得到服务的URL对象如下:

URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map); // 内容 :dubbo://169.254.38.78:20880/com.zzz.dubbodemo.api.service.DemoService?anyhost=true&application=sp1&bind.ip=127.0.0.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.zzz.dubbodemo.api.service.DemoService&methods=add&pid=14140&side=provider×tamp=1535640387238
 
if (registryURLs != null && !registryURLs.isEmpty()) {
    for (URL registryURL : registryURLs) {
        url = url.addParameterIfAbsent(Constants.DYNAMIC_KEY, registryURL.getParameter(Constants.DYNAMIC_KEY));
        URL monitorUrl = loadMonitor(registryURL);
        if (monitorUrl != null) {
            url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
        }
        if (logger.isInfoEnabled()) {
            logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
        }

        // For providers, this is used to enable custom proxy to generate invoker
        String proxy = url.getParameter(Constants.PROXY_KEY);
        if (StringUtils.isNotEmpty(proxy)) {
            registryURL = registryURL.addParameter(Constants.PROXY_KEY, proxy);
        }

        Invoker invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
        DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);

        Exporter exporter = protocol.export(wrapperInvoker);
        exporters.add(exporter);
    }
}

循环注册中心注册每个暴露服务

registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString())//把服务URL添加到注册URL参数为export中得到一个新的URL

使用spi 获得的proxyFactory 将接口的实现类对象和接口还有 得到的新URL得到invoker(详细过程看我的另一博客) 然后在创建一个DelegateProviderMetaDataInvoker wrapperInvoker 对象将该invoker 和服务的配置信息对象包含起来

然后使用protocol.export(wrapperInvoker); 进行服务发布 并返回Exporter 

由于wrapperInvoker包含的URL的是注册URL 所以protocol.export(wrapperInvoker);最终会执行到RegistryProtocol..export(wrapperInvoker) (详细了解Dubbo SPI)

//方法里面执行的这个行就是将服务绑定到netty 服务器上(默认的)该originInvoker 包含的URL 是注册中心得 URL 有个export参数对应的值 是服务的URl
final ExporterChangeableWrapper exporter = doLocalExport(originInvoker);
final Invoker invokerDelegete = new InvokerDelegete(originInvoker, getProviderUrl(originInvoker));
exporter = new ExporterChangeableWrapper((Exporter) protocol.export(invokerDelegete), originInvoker);

//getProviderUrl(originInvoker) 就是后去originInvoker 里面注册URL 参数export对应的字符串并通过URL的静态方法转化为URL对象 就拿到了提供者服务的URL

然后创建了Invoker invokerDelegete 包含了可以执行到我们具体实现类对象的invoker和提供者服务的URL

然后执行 protocol.export(invokerDelegete), originInvoker); 应为invokerDelegete 包含的URL 是提供者的服务 默认是Dubbo协议

所有经过一些wrapper会执行到DubboProtocol.export(Invoker invoker)

String key = serviceKey(url); //借口类加上本地服务器端口号例如:com.zzz.dubbodemo.api.service.DemoService:20880

DubboExporter exporter = new DubboExporter(invoker, key, exporterMap);
exporterMap.put(key, exporter);

创建DubboExporter 对象并添加缓存 将key 和exporterMap对象都给DubboExporter 是方便将自己移除缓存

openServer(url);//提供者URL 暴露出去 就是发布到服务器上已提供远程连接调用

提供者服务配置是怎么注册到服务中心的

在 RegistryProtocol..export(wrapperInvoker) 方法中一个是调用doLocalExport(originInvoker)将服务URL发布到netty服务器是上,还有一个就是将注册URL 注册到注册中心

 

URL providerUrl = getProviderUrl(originInvoker); //移除invoker里面url的参数"dynamic", "enabled" 的full属性

 

然后再删除.removeParameter(Constants.MONITOR_KEY)

                .removeParameter(Constants.BIND_IP_KEY)

                .removeParameter(Constants.BIND_PORT_KEY)

                .removeParameter(QOS_ENABLE)

                .removeParameter(QOS_PORT)

                .removeParameter(ACCEPT_FOREIGN_IP);

和以点开头的参数

这些参数得到新的URL 就是registedProviderUrl

register(registryUrl, registeredProviderUrl);
Registry registry = registryFactory.getRegistry(registryUrl);
registry.register(registedProviderUrl);

registryUrl 的默认协议是zookeeper 所以registry  就是ZookeeperRegister继承于FailbackRegistry

super.register(url); //registered.add(url);将url添加到缓存当中
doRegister(url);
zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, true));

然后注册到了注册中心

 

 

 

 

 

你可能感兴趣的:(dubbo 2.6.2 服务暴露过程)