dubbo服务的发布

dubbo服务的发布的入口也在ServiceBean中,实现ApplicationListener接口,在spring容器初始代启动完成之后,会回调接口的onApplicationEvent方法。

步骤
1. ServiceBean.onApplicationEvent()方法调用ServiceConfig.export()->doExport()
2. doExport方法中,会调用 checkApplication(), checkRegistry(), checkProtocol()等方法,
这些方法会检测 dubbo的配置是否在spring配置文件通过dubbo标签的方式生成,如果没有则会读取 dubbo.properties文件中的配置,并初始代。
3. 接下来调用ServiceConfig.doExportUrls()方法,首先会调用loadRegistries()方法加载注册中心,这里又调用了checkRegistry方法初始代,然后对RegistryConfig进行了读取和处理,封装成url列表返回。(对于多注册中心的配置,官方文档上说是根据逗号进行分隔,但读取代码发现需要以|进行分隔), 注意对于在标签中指定了registry属性的ServiceBean,会加载BeanDefinition时就加载了注册中心。
4. 接下来doExportUrls方法会遍历前面返回的url,并把服务发布到不同的注册中心中。
5. doExportUrlsFor1Protocol方法,首先会获取本机的ip发部服务的端口号,在dubbo.properties配置文件中指定了dubbo.protocol.host属性的,直接读取,否则能过InetAddress.getLocalHost().getHostAddress()获取。
6. 把dubbo的配置信息封装到map中,并生成对应的url.如下
http://10.0.5.71:8080/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&organization=dubbo&owner=william&pid=12108&side=provider&timestamp=1484906734130

 7. 根据服务具体实现,实现接口以及regitryUrl从代理工厂ProxyFactory获取代理Invoker(继承于AbstractProxyInvoker),它是对具体实现的一种代理。
 8. Protocol.export(invoker) 暴露服务invoker, 调用Protocol$Adpative(生成适配类)的export方法

      com.alibaba.dubbo.common.URL url = invoker.getUrl();
        String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
  com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.geExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class)
                .getExtension(extName);
        return extension.export(arg0) 
9.  Invoker包含上一步传入的RegistryUrl, registryUrl的protocol值为registry,接下来会调用RegistryProtocol去暴露服务。
Protocol有两个ProtocolListenerWrapper和ProtocolFilterWrapper对于协议为REGISTRY_PROTOCOL直接跳过,最终由RegistryProtocol处理export的过程

RegistryProtocol暴露服务过程

1. 执行 doLocalExport(originInvoker), 实际是调用DubboProtocol.export()暴露服务,启动提供者。
2. getRegistedProviderUrl(originInvoker)拿到提供者的地址,注册到注册中心。
3. 提供者订阅,即对这个服务提供者的地址进行监听,registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener),当节点发生发生变代时,注册中心会通知各节点。实际调用OverrideListener.notify方法,重新暴露服务。
4. 包装第一步中返回的exporter返回,并重写unexport方法,到服务反暴露时,

取消订阅。
下面详细看一看doLocalExport方法

  private <T> ExporterChangeableWrapper<T>  doLocalExport(final Invoker<T> originInvoker){
        //1. 从invoker中获取 提供者的url  dubbo://172.30.18.26:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&organization=dubbo&pid=7376&side=provider&timestamp=1486718882603
        // 作为bounds中的key
        String key = getCacheKey(originInvoker);
        // 2.从bounds中获取exporter, 单例实现
        ExporterChangeableWrapper<T> exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
        if (exporter == null) {
            synchronized (bounds) {
                exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
                if (exporter == null) {
                    //3.根据invoker也提供者的地址实例代出Invoker的实现 
                    final Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));
                    //4. 调用protocol.export暴露服务,返回 exporter,并存到bounds中,根据提供者的协议,调用具体的Protocol实现的export方法
                    exporter = new ExporterChangeableWrapper<T>((Exporter<T>)protocol.export(invokerDelegete), originInvoker);
                    bounds.put(key, exporter);
                }
            }
        }
        return (ExporterChangeableWrapper<T>) exporter;
    }

DubboProtocol暴露服务过程

1. 根据url构建key,缓存exporter到exporterMap中
2. 调用openService->createServer打开服务,传入requestHandler
        /默认使用netty
        server = Exchangers.bind(url, requestHandler);
3. 返回exporter对象
4. ExchangeHandler.reply方法处理消费者的消息 ,调用invoker.invoke执行具体的方法 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值