dubbo服务暴露-远程暴露(三)

说完本地暴露之后,我们说远程暴露,也是面试喜欢问的。

我们引用下官网的说法,与导出服务到本地相比,导出服务到远程的过程要复杂不少,其包含了服务导出与服务注册两个过程

那我们就分开两部分开始叙述

服务导出

我们debug
在这里插入图片描述生成Invoker,我们不说了。自己debug进去,分析就好了,我们主要说这个
Exporter<?> exporter = protocol.export(wrapperInvoker),debug走进去
在这里插入图片描述我们主要看这两个实现类,分别打上断点,然后放行,会发现首先进去RegistryProtocol这个类中,看类名,我们猜测是和注册有关,但是我们不是先说导出,在说服务注册吗?其实服务注册就是RegistryProtocol方法中,OK,我们看RegistryProtocol中的实现

@Override
    public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
    // 导出服务
    final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
    // 获取注册中心 URL,以 zookeeper 注册中心为例,得到的示例 URL 如下:
    // zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&dubbo=2.0.2&export=dubbo%3A%2F%2F172.17.48.52%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider
    URL registryUrl = getRegistryUrl(originInvoker);
    // 根据 URL 加载 Registry 实现类,比如 ZookeeperRegistry
    final Registry registry = getRegistry(originInvoker);
    // 获取已注册的服务提供者 URL,比如:
    // dubbo://172.17.48.52:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.2&generic=false&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello
    final URL registeredProviderUrl = getRegisteredProviderUrl(originInvoker);
        boolean register = registedProviderUrl.getParameter("register", true);
		// 向服务提供者与消费者注册表中注册服务提供者
        ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registedProviderUrl);
		//进行注册
        if (register) {
            register(registryUrl, registedProviderUrl);
            ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
        }
		....
    }

我们看源码,知道了,先导出服务,然后在想注册中心注册服务。我们先到导出服务源码:
在这里插入图片描述还记得我们前面说的,有两个和protocol有关,一个是RegistryProtocol,一个是DubboProtocol,我们发现这次调用的是DubboProtocol的实现。

@Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        URL url = invoker.getUrl();

        // export service.
        String key = serviceKey(url);
        DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
        exporterMap.put(key, exporter);
		....
		//我们说URL是dubbo的载体,很多模块之间都是靠url来进行传递的,所以我们看这个方法对url做了什么
        openServer(url);
        optimizeSerialization(url);
        return exporter;
    }

看一下我们的url是什么
在这里插入图片描述这是和我们暴露的服务有关的一些信息
在这里插入图片描述如果服务没有开启,我们需要先创建服务,继续createService(url)
在这里插入图片描述服务器的创建在bind中
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述我们知道dubbo底层是用netty的,所以直接进入nettyTransporter实现类
在这里插入图片描述在这里插入图片描述OK,其实到这里我们发现,openServer(url),其实就是创建netty服务器,如果你不了解netty。需要看了,因为面试官,问你远程服务暴露的时候,就会接着问netty的一些知识了。

自此,服务远程导出就完成了,我们开始注册

当我们开启完netty服务,然后返回一个export,我们回到RegistryProtocol.export方法中,
在这里插入图片描述到注册这个地方,它传递了两个参数,registryUrl(zookeeper注册中心地址)和registedProviderUrl(服务暴露地址)
在这里插入图片描述我们继续跟进:
在这里插入图片描述在这里插入图片描述创建注册中心:getRegistry():
在这里插入图片描述

public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) {
    ...
    // 创建 Zookeeper 客户端,默认为 CuratorZookeeperTransporter
    zkClient = zookeeperTransporter.connect(url);
    // 添加状态监听器
    zkClient.addStateListener(new StateListener() {
        @Override
        public void stateChanged(int state) {
            if (state == RECONNECTED) {
                try {
                    recover();
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
    });
}

我们完成了创建 Zookeeper 客户端。接下来就是把服务注册到zk上

dubbo默认的是FailbackRegistry
在这里插入图片描述不同的注册中心,进入不同的方法实现中,我们用的是zk,进入zookeeperRegistry实现类
在这里插入图片描述
在zk上,创建节点:

@Override
    public void create(String path, boolean ephemeral) {
        int i = path.lastIndexOf('/');
        if (i > 0) {
            String parentPath = path.substring(0, i);
            if (!checkExists(parentPath)) {
                create(parentPath, false);
            }
        }
        //创建临时或持久节点
        if (ephemeral) {
            createEphemeral(path);
        } else {
            createPersistent(path);
        }
    }

到此关于服务注册的过程就分析完了。整个过程可简单总结为:先创建注册中心实例,之后再通过注册中心实例注册服务

总结

远程服务暴露过程,都做了哪些事情?

  • 开启一个netty服务器
  • 创建zk客户端
  • 在zk上,创建节点

我只是做了一个简单的大概的总结,还有很多细节,需要读者debug,一步步分析。

到这里,dubbo服务暴露就简单的分析完了,源码的分析和理解,需要不断的去看,最权威的还是需要看文档dubbo服务导出
有不对的地方,望海涵,希望读者指出。

最后我们回到刚开始我们的面试题在想想:

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

其实在远程暴露中,还能延伸很多提问:
服务提供者能实现失效踢出是根据什么原理?
dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?
zookeeper实现分布式锁
zookeeper选举机制
BIO、NIO、AIO分别是什么?
说说你对Netty的了解?
同步与异步、阻塞与非阻塞的区别

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值