10、dubbo源码分析 之 服务远程暴露(下)

在前面的文章我们分析了一下 dubbo 远程服务暴露过程中通过 Netty 进行 Socket 服务暴露。使得远程客户端可以访问这个暴露的服务,这个只是解决了访问之前点到点的服务调用。对于分步式环境当中,越来越多的服务我们如何管理并且治理这些服务是一个问题。因此 dubbo 引入了注册中心这个概念,把服务暴露、服务调用的信息保存到注册中心上面。并且还可以订阅注册中心,实现服务自动发现。因为 dubbo 远程暴露里面的过程还是比较复杂的,所以我就分为三个文章来讲解 dubbo 的远程暴露:

  • dubbo 远程暴露 – Netty 暴露服务
  • dubbo 远程暴露 – Zookeeper 连接
  • dubbo 远程暴露 – Zookeeper 注册 & 订阅

在上篇文章中我们分析 dubbo 是如何创建 zookeeper 这个注册中心的。下面我们就来分析一下 dubbo 究竟使用 zookeeper 这个组件来做了哪些事。

1、RegistryProtocol#export

下面就是 dubbo 暴露的核心步骤的代码,可能由于版本的原因(下面的代码基于 2.6.1)代码会有所差异但是核心思想不变。

    public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
        //export invoker
        final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);

        URL registryUrl = getRegistryUrl(originInvoker);

        //registry provider
        final Registry registry = getRegistry(originInvoker);
        final URL registedProviderUrl = getRegistedProviderUrl(originInvoker);

        //to judge to delay publish whether or not
        boolean register = registedProviderUrl.getParameter("register", true);

        ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registedProviderUrl);

        if (register) {
            register(registryUrl, registedProviderUrl);
            ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
        }

        // Subscribe the override data
        // FIXME When the provider subscribes, it will affect the scene : a certain JVM exposes the service and call the same service. Because the subscribed is cached key with the name of the service, it causes the subscription information to cover.
        final URL overrideSubscribeUrl = getSubscribedOverrideUrl(registedProviderUrl);
        final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
        overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
        registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
        //Ensure that a new exporter instance is returned every time export
        return new DestroyableExporter<T>(exporter, originInvoker, overrideSubscribeUrl, registedProviderUrl);
    }

在之前的文章中分析了 dubbo 通过 netty 暴露服务,然后获取到 zookeeper 注册中心 --- ZookeeperRegistry。下面就是把 Provider (服务提供者)的信息注册到注册中心上。这样 Consumer (服务消费者)就可以通过 Registry (注册中心)获取到 Provider 的信息。这样就解耦了 Provider 与 Consumer,并且可以通过 Registry 来修改路由规则、权重等控制。这样就达到的服务的治理。下面我们就来讲解一下,服务的注册与订阅。

2、ZookeeperRegistry#register

这个就是把服务信息注册到 Zookeeper 上面去。

1、AbstractRegistry#register添加注册Set<URL> registered(已注册的URL),用于失败重试。
2、ZookeeperRegistry#doRegister通过上篇 blog 讲解的获取到的 ZookeeperClient 把服务信息注册到 Zookeeper 上。此时的 URL 为:

dubbo://192.168.75.1:20880/com.alibaba.dubbo.demo.DemoService?
anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&
interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=2076&
side=provider&timestamp=1522237459900

dubbo 会基于这个 URL 生成一个新的URL,生成规则为:

"/dubbo/" + url里面的interface的值 + "/providers/" + URL.encode(url)

生成后的值 :

/dubbo/com.alibaba.dubbo.demo.DemoService/providers/
dubbo%3A%2F%2F192.168.75.1%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D2076%26side%3Dprovider%26timestamp%3D1522237459900

然后在 Zookeeper 上面把 /dubbo/com.alibaba.dubbo.demo.DemoService/providers/ 创建成持久化节点,而后面部分的 URL 就会创建成临时节点。

把服务提供者信息创建成临时节点的好处就是如果当前服务挂掉,这个节点就会自动删除。这样失效服务就可以自动剔除。

Zookeeper 持久化节点 和临时节点有什么区别?
持久化节点:一旦被创建,触发主动删除掉,否则就一直存储在ZK里面。
临时节点:与客户端会话绑定,一旦客户端会话失效,这个客户端端所创建的所有临时节点都会被删除。

3、ZookeeperRegistry#subscribe

通过订阅 Zookeeper 上面的的节点信息变更, 可以通过 dubbo-admin来修改服务路由规则、权重等。

1、创建一个 NotifyListener 实例 OverrideListener, 当收到服务变更通知时触发。
2、在 Zookeeper 注册中心创建持久化节点/dubbo/com.alibaba.dubbo.demo.DemoService/configurators,用于接收 dubbo-admin这个客户端上对于集群的服务治理。

ZookeeperRegistry#doSubscribe {
    zkClient.create(path, false)
}

3、启动加入订阅/dubbo/com.alibaba.dubbo.demo.DemoService/configurators,如果该节点信息发生改变,就会交给FailbackRegistry.notify处理。

ZookeeperRegistry#doSubscribe {
    zkClient.addChildListener(path, zkListener)
}

4、FailbackRegistry#notify

1、把服务端的注册 url 信息更新到本地缓存(AbstractRegistry#saveProperties),以Window为例:

C:\Users\Carl\.dubbo\dubbo-registry-10.65.209.12.cache

2、调用传入的OverrideListener#notify,如果修改了 URL 信息,调用RegistryProtocol.this.doChangeLocalExport(originInvoker, newUrl)重新暴露当前服务。

前面二篇加上这一篇就是 dubbo 远程服务暴露的整个过程。下面这张图片就是 dubbo 进行服务暴露、服务远程调用添加 dubbo monitor 后 Zookeeper 上面 dubbo 节点的结构图。

这里写图片描述

关于zookeeper在Dubbo中扮演了一个什么角色,起到了什么作用啊?,大家可以看一下这篇知乎上面的问答。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容