前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dubbo注册中心 - zookeeper

Dubbo注册中心 - zookeeper

作者头像
虞大大
发布2020-11-05 18:38:44
1.1K0
发布2020-11-05 18:38:44
举报
文章被收录于专栏:码云大作战码云大作战

一、Dubbo中注册中心的作用

在Dubbo的学习中可以看到注册中心是Dubbo的核心组件,注册中心主要有以下作用:

(1)动态加入。

服务提供者可以通过注册中心将自己暴露给其他消费者,无须在消费者服务中逐个更新配置文件。

(2)动态发现

一个消费者可以通过订阅的方式动态的感知新的配置、路由参数和新的服务提供者,无须重启服务使之生效。

(3)动态调整

注册中心支持参数的动态调整,新参数自动更新到所有相关服务节点。

(4)统一配置

由于注册中心的存在,只需要配置注册中心的地址,而无需配置其他服务提供者的配置,避免了本地配置导致每个服务的配置不一致的问题。

二、Zookeeper数据结构

如图所示是zookeeper的节点信息。

如上图所示,可以看到zookeeper是一个树形结构的注册中心,并且在节点中存在持久化节点和临时节点。

树形结构中元素:

(1)根节点

zookeeper树的根结点,默认是/dubbo。也可以通过配置group属性来设置根结点,<dubbo:registry group="name">

(2)持久化节点

分别是providers、consumers、configurations、routes,并且这四个节点都属于持久化节点。

(3)临时节点 - providers目录

providers目录中包含了多个服务提供者的URL信息,属于临时节点。

(4)临时节点 - consumers目录

consumers目录中包含了多个消费者的URL信息,属于临时节点。

(5)临时节点 - configurations目录

configurations目录中包含了多个服务提供者动态配置的URL信息,属于临时节点。

(6)临时节点 - routes目录

routes目录中包含了多个用于消费者路由策略的URL信息,属于临时信息。

· 持久节点和临时节点

持久节点-表示服务节点一但被创建,触发触发主动删除,否则一直存储在zk中,注册中心重启也会存在,节点不会丢失。

临时节点-表示服务注册后连接丢失或session超时,注册的临时节点就会被自动删除。

三、zookeeper的订阅/发布

在传统项目中,我们通常会把配置信息写入配置文件中,如果配置需要变更,需要修改配置文件并刷新内存重新加载或重启服务。而如果我们使用注册中心帮助我们来更新配置信息则会方便很多。

比如上述的节点信息,客户端只需要关心/consumers节点即可,即使当providers目录中的其中一个服务端宕机了,在客户端的配置中也不需要更改配置信息。

上述节点信息中的处理,他会动态的删除宕机的服务临时节点,并且刷新/providers目录。对于客户端对该服务接口的调用由于负载均衡处理,并不会受到影响。

· 服务发布的实现 - zookeeper

服务提供者和消费者在启动时都会将自己注册到注册中心,服务提供者的注册是为了让消费者感知服务的存在,发起远程调用,也让服务治理中心感知有新的服务提供者上线。

消费者的注册是为了让服务治理中心发现自己。

dubbo中服务发布节点创建相关代码:

代码语言:javascript
复制
protected void doRegister(URL url) {
    try {
zkClient.create(toUrlPath(url),                    url.getParameter(Constants.DYNAMIC_KEY, true));
    } catch (Throwable e) {
        throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
    }
}

· 订阅的实现 - zookeeper

在服务暴露时,服务端服务会订阅configuration监听动态配置。消费者启动时,会订阅providers、routes、configurations三个节点目录,分别监听服务提供者、路由和动态配置的变更通知。

目前客户端订阅的方式,在客户端刚启动时,会从注册中心主动读取全量的配置信息数据,并且在订阅的节点上注册一个watcher,客户端与注册中心保持长连接。在客户端运行中则是通过注册中心根据watcher来通知客户端,客户端接到通知后会进行事件处理,dubbo中的源码是会把配置信息重新读取下来。

订阅关系如下图所示:

dubbo中订阅代码如下:

代码语言:javascript
复制
List<URL> urls = new ArrayList<URL>();
//需要订阅的路径
for (String path : toCategoriesPath(url)) {
    ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
    if (listeners == null) {        //缓存判断
zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, ChildListener>());
        listeners = zkListeners.get(url);
    }    //订阅缓存判断
ChildListener zkListener = listeners.get(listener);
    if (zkListener == null) {
        listeners.putIfAbsent(listener, new ChildListener() {
            @Override
            public void childChanged(String parentPath, List<String> currentChilds) {
                ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
            }
        });
        zkListener = listeners.get(listener);
    }    //创建订阅的持久化节点
zkClient.create(path, false);
    //该结点下子路径    List<String> children = zkClient.addChildListener(path, zkListener);
    if (children != null) {
        urls.addAll(toUrlsWithEmpty(url, path, children));
    }
}notify(url, listener, urls);

上述代码会执行多次,直到服务端服务订阅了configurations节点,客户端引用的服务端服务订阅了providers、routes、configurations节点。

notify方法,主要是触发订阅事件,进行订阅后的处理。

providers节点,则订阅方会更新本地目录的invoker服务列表。

routes节点,则订阅方会更新本地路由规则列表。

configurations节点,则订阅方会更新本地动态参数列表。

参考资料:

深入理解Apache Dubbo与实战 - 第3章 Dubbo注册中心

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码云大作战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档