dubbo服务暴露(一)

讲服务暴露之前,我们先思考下几个问题:

  1. 服务暴露都做了哪些事
  2. 本地暴露和远程暴露的区别
  3. 为什么需要本地暴露

先说一个整体流程,文档是最好的说明:dubbo文档
服务提供者暴露一个服务的详细过程
在这里插入图片描述在这里插入图片描述文档说我们从ServiceBean开始,OK,那我们就从ServiceBean的继承开始,发现它是实现ApplicationListener,这是spring的事件机制,监听spring容器初始化完成,从onApplicationEvent开始

@Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (isDelay() && !isExported() && !isUnexported()) {
            if (logger.isInfoEnabled()) {
                logger.info("The service ready on spring started. service: " + getInterface());
            }
            export();
        }
    }

debug,继续走export(),发现走到ServiceConfig类中

public synchronized void export() {
        //这块,就是看是否配置了延迟暴露
        if (delay != null && delay > 0) {
            delayExportExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    doExport();
                }
            }, delay, TimeUnit.MILLISECONDS);
        } else {
            doExport();
        }
    }

然后看doExport()方法:

protected synchronized void doExport() {
        ....
        //上面就是检查interface的合法性,ProviderConfig、ApplicationConfig 等核心配置类对象是否为空
        //检测本地存根配置等等,这些大家可以自行分析,我们主要说这个doExportUrls()
        doExportUrls();
        ...
    }

进入这个方法:

private void doExportUrls() {
		//加载注册中心,可以有多个注册中心
        List<URL> registryURLs = loadRegistries(true);
        for (ProtocolConfig protocolConfig : protocols) {
        //遍历不同的协议,并在每个协议下导出服务
            doExportUrlsFor1Protocol(protocolConfig, registryURLs);
        }
    }

我们的注册中心地址,是一个List(因为dubbo是多注册中心)
我用的是zk做注册中心
我们的配置协议(当然也是多协议,缺省是dubbo协议)
协议默认是dubbo协议接下来我们开始分析doExportUrlsFor1Protocol(protocolConfig, registryURLs):

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
        ...
			//这个是把要暴露的接口方法给组成数组,然后在下面以,分割,放如map中
            String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
            if (methods.length == 0) {
                logger.warn("NO method found in service interface " + interfaceClass.getName());
                map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
            } else {
                map.put(Constants.METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
            }
        }
        //版本、时间戳、方法名以及各种配置对象的字段信息放入到 map 中,map 中的内容将作为 URL 的查询字符串。构建好 map 后,紧接着是获取上下文路径、主机名以及端口号等信息。最后将 map 和主机名等数据传给 URL 构造方法创建 URL 对象
        URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
        ...
            if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
            //本地暴露
                exportLocal(url);
            }
           //远程暴露
            if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
               ...
                        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);
                    }
                } 
            }
        }
        this.urls.add(url);
    }

我们分别看下URL和map参数:
URLmap

总结

这个方法onApplicationEvent做的事情有哪些:

  • 加载注册中心,根据不同协议进行不同的服务导出(dubbo是多协议,多注册中心)
  • 在服务导出的时候,我们进行各种的检查配置,然后为map赋值和组装URL
  • map和URL组装好之后,根据scope进行本地暴露或远程暴露或都暴露等

目前为止,我们只看到了ServiceConfig的身影,和ref服务类,别着急,接下来我们开始分析重要的本地暴露和远程暴露

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值