Zookeeper案例之监听配置中心

目录

一、概述

二、案例


一、概述

在分布式系统中,每个微服务可能都会有自己的配置文件信息,比如数据库连接、用户名和密码信息都配置在配置文件中,微服务读取配置文件,将配置文件信息存入缓存中。

假设我们的配置信息发生变化时,我们还需要重新加载缓存,这比较麻烦。在zookeeper中,我们学习了watcher监听机制,利用监听机制可能轻松实现当配置信息发生变化时,应用程序第一时间发现配置变化并重新加载最新的配置信息。

二、案例

这里我们以一个简单的案例说明在zookeeper中如何利用watcher监听机制实现客户端对配置信息的动态感知。

实现步骤大体如下:

  • 1、使用终端在zookeeper中事先创建一些配置信息;
  • 2、Java客户端连接到zookeeper服务器;
  • 3、客户端读取zookeeper中的配置信息,并且注册watcher监听,将配置信息保存起来;
  • 4、使用终端对zookeeper中的配置信息进行修改;
  • 5、客户端监听到zookeeper中的配置已经更改,通过watcher的回调方法捕获到节点数据变化事件;
  • 6、客户端重新获取到最新的配置;

【a】使用终端在zookeeper中事先创建一些配置信息

[zk: localhost:2181(CONNECTED) 43] create /dbconfig "dbconfig"
Created /dbconfig
[zk: localhost:2181(CONNECTED) 44] create /dbconfig/url "jdbc:oracle:thin:@192.168.2.58:1521:orcl"
Created /dbconfig/url
[zk: localhost:2181(CONNECTED) 45] create /dbconfig/username "wfwzhxg"                            
Created /dbconfig/username
[zk: localhost:2181(CONNECTED) 46] create /dbconfig/password "wfwzhxg"
Created /dbconfig/password
[zk: localhost:2181(CONNECTED) 47] ls /dbconfig 
[password, url, username]

以上我们创建了三个节点:

  • url:jdbc:oracle:thin:@192.168.2.58:1521:orcl
  • username:wfwzhxg
  • password:wfwzhxg

【b】Java客户端相关代码

import com.wsh.zookeeper.zookeeperapidemo.watcher.ZookeeperWatcherExists;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class ZookeeperConfigDemo {
    private String url;
    private String username;
    private String password;

    private static final String ZOOKEEPER_SERVER_ADDRESS = "192.168.179.133:2181";
    private static final Logger logger = LoggerFactory.getLogger(ZookeeperWatcherExists.class);
    private static ZooKeeper zooKeeper = null;

    public ZookeeperConfigDemo() {
        try {
            Watcher watcher = new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    try {
                        // 捕获事件状态
                        if (event.getType() == Event.EventType.None) {
                            if (event.getState() == Event.KeeperState.SyncConnected) {
                                logger.info("连接成功...");
                            } else if (event.getState() == Event.KeeperState.Disconnected) {
                                logger.info("连接断开...");
                            } else if (event.getState() == Event.KeeperState.Expired) {
                                logger.info("连接超时...");
                                // 超时后服务器端已经将连接释放,需要重新连接服务器端
                                zooKeeper = new ZooKeeper(ZOOKEEPER_SERVER_ADDRESS, 3000, this);
                            } else if (event.getState() == Event.KeeperState.AuthFailed) {
                                logger.info("验证失败...");
                            }
                        } else if (event.getType() == Event.EventType.NodeDataChanged) {
                            // 当配置信息发生变化时
                            initValue();
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            };
            zooKeeper = new ZooKeeper(ZOOKEEPER_SERVER_ADDRESS, 3000, watcher);
            initValue();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initValue() {
        this.url = getDbUrl();
        this.username = getDbUsername();
        this.password = getDbPassword();
    }

    private String getDbUrl() {
        try {
            byte[] urlData = zooKeeper.getData("/dbconfig/url", true, null);
            return new String(urlData);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getDbUsername() {
        try {
            byte[] data = zooKeeper.getData("/dbconfig/username", true, null);
            return new String(data);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getDbPassword() {
        try {
            byte[] data = zooKeeper.getData("/dbconfig/password", true, null);
            return new String(data);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public static void main(String[] args) throws InterruptedException {
        ZookeeperConfigDemo zookeeperConfigDemo = new ZookeeperConfigDemo();
        for (int i = 0; i < 30; i++) {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("dburl : " + zookeeperConfigDemo.getDbUrl());
            System.out.println("dbusername : " + zookeeperConfigDemo.getDbUsername());
            System.out.println("dbpassword : " + zookeeperConfigDemo.getPassword());
            System.out.println("####################################################");
        }
    }

}

【c】使用终端对zookeeper中的配置信息进行修改

[zk: localhost:2181(CONNECTED) 53] set /dbconfig/username zhxg2       #修改用户名                          
cZxid = 0xfa
ctime = Fri Dec 25 10:41:09 CST 2020
mZxid = 0x106
mtime = Fri Dec 25 11:03:15 CST 2020
pZxid = 0xfa
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 54] set /dbconfig/password zhxg2        #修改密码                        
cZxid = 0xfb
ctime = Fri Dec 25 10:41:16 CST 2020
mZxid = 0x107
mtime = Fri Dec 25 11:03:18 CST 2020
pZxid = 0xfb
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 55] set /dbconfig/url jdbc:oracle:thin:@192.168.35.106:1521:orcl  #修改数据库连接URL
cZxid = 0xf9
ctime = Fri Dec 25 10:40:58 CST 2020
mZxid = 0x108
mtime = Fri Dec 25 11:03:21 CST 2020
pZxid = 0xf9
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 42
numChildren = 0

【d】客户端动态感知配置变化

观察后端日志:

dburl : jdbc:oracle:thin:@192.168.2.58:1521:orcl
dbusername : zhxg2
dbpassword : zhxg
####################################################
dburl : jdbc:oracle:thin:@192.168.2.58:1521:orcl
dbusername : zhxg2
dbpassword : zhxg2
####################################################
dburl : jdbc:oracle:thin:@192.168.35.106:1521:orcl
dbusername : zhxg2
dbpassword : zhxg2
####################################################

可以看到,客户端实时监听到zookeeper服务端配置信息的变化。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值