Ⅶ:教你一招利用zookeeper作为服务的配置中心

2021最新zookeeper系列

❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️

Ⅰ:zookeeper的单机安装 - 详细教程:https://blog.csdn.net/Kevinnsm/article/details/116134397?spm=1001.2014.3001.5501

Ⅱ:zookeeper的相关shell命令:https://blog.csdn.net/Kevinnsm/article/details/116137602?spm=1001.2014.3001.5501

Ⅲ:zookeeper之查看节点的状态信息:https://blog.csdn.net/Kevinnsm/article/details/116143218?spm=1001.2014.3001.5501

Ⅳ:zookeeper的acl权限控制:https://blog.csdn.net/Kevinnsm/article/details/116167394?spm=1001.2014.3001.5501

Ⅴ:zookeeper的相关Java Api:https://blog.csdn.net/Kevinnsm/article/details/116462557?spm=1001.2014.3001.5501

Ⅵ:zookeeper的Watcher事件监听机制:https://blog.csdn.net/Kevinnsm/article/details/116501842?spm=1001.2014.3001.5501

Ⅶ:教你一招利用zookeeper作为服务的配置中心:https://blog.csdn.net/Kevinnsm/article/details/116542974?spm=1001.2014.3001.5501

❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️


前置:–》把握住Watcher流程《–

1、连接zookeeper服务器
2、连接时必须使当前线程等待(等待其他线程创建连接zookeeper服务成功,使用计数器实现)
3、执行回调函数process
4、释放当前线程

一、环境搭建

演示mysql的连接配置(将mysql连接属性配置到zookeeper服务器)

Ⅰ、使用工具

使用云服务器作为zookeeper的演示环境,本地使用xshell远程连接
如果不知,请移步:https://blog.csdn.net/Kevinnsm/article/details/116134397?spm=1001.2014.3001.5501

Ⅱ、创建节点

create /config “config”
create /config/mysql “datasource”
create /config/mysql/driver "com.mysql.cj.jdbc.Driver
create /config/mysql/url "jdbc:mysql://127.0.0.1/test?serverTimezone=UTC
create /config/mysql/username “root”
create /config/mysql/password “xxxxxxx”
在这里插入图片描述

Ⅲ、代码编写

package com.zookeeper.config;

import com.zookeeper.watcher.WatcherConnection;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;

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

/**
 * @author:抱着鱼睡觉的喵喵
 * @date:2021/5/8
 * @description:
 */
public class ZookeeperConfigCenter implements Watcher {
//mysql的本地变量
    private String driver;
    private String url;
    private String username;
    private String password;
    static ZooKeeper zooKeeper;
    static CountDownLatch countDownLatch = new CountDownLatch(1);
    final static String IP = "8.140.37.103:2181";
//构造函数,只要一创建该类,就执行getProperty()方法
    public ZookeeperConfigCenter() {
        getProperty();
    }
    //重写回调函数
    @Override
    public void process(WatchedEvent watchedEvent) {
        try {
            if (watchedEvent.getType() == Event.EventType.None) {
                if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                    System.out.println("连接成功");
                    //如果连接成功,放行当前线程
                    countDownLatch.countDown();
                } else if (watchedEvent.getState() == Event.KeeperState.Disconnected) {
                    System.out.println("连接中断");
                } else if (watchedEvent.getState() == Event.KeeperState.Expired) {
                    System.out.println("连接超时");
                    //如果连接超时就重新进行连接
                    zooKeeper = new ZooKeeper(IP, 5000, new WatcherConnection());
                } else if (watchedEvent.getState() == Event.KeeperState.AuthFailed) {
                    System.out.println("验证失败");
                }
                //如果监听到节点数据发生了变化,就重新连接读取节点数据
            } else if (watchedEvent.getType() == Event.EventType.NodeDataChanged) {
                getProperty();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//核心方法
    public void getProperty() {
        try {
        //连接zookeeper服务
            zooKeeper = new ZooKeeper(IP, 20000, this);
            //等待其他线程连接zookeeper服务
            countDownLatch.await();
            this.driver = new String(zooKeeper.getData("/config/mysql/driver", true, null));
            this.url = new String(zooKeeper.getData("/config/mysql/url", true, null));
            this.username = new String(zooKeeper.getData("/config/mysql/username", true, null));
            this.password = new String(zooKeeper.getData("/config/mysql/password", true, null));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test() {
        try {
            ZookeeperConfigCenter configCenter = new ZookeeperConfigCenter();
            for (int i = 1; i < 6; i++) {
                System.out.println(configCenter.driver);
                System.out.println(configCenter.url);
                System.out.println(configCenter.username);
                System.out.println(configCenter.password);
                //休眠10秒
                Thread.sleep(10000);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

另外也用到了一个简单的连接类作为zookeeper连接超时的回调处,然后进性重新连接(实现了watcher接口

public class WatcherConnection implements Watcher {
    static CountDownLatch countDownLatch = new CountDownLatch(1);
    //计数器
    static ZooKeeper zooKeeper;
    public static void main(String[] args) {
        try {
            zooKeeper = new ZooKeeper("123.57.252.59:2181", 5000, new WatcherConnection());
            countDownLatch.await();
            Thread.sleep(10000);
            zooKeeper.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void process(WatchedEvent watchedEvent) {
        try {
            if (watchedEvent.getType() == Event.EventType.None) {
                if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                    System.out.println("连接成功!");
                    countDownLatch.countDown();
                } else if (watchedEvent.getState() == Event.KeeperState.Disconnected) {
                    System.out.println("断开连接");
                } else if (watchedEvent.getState() == Event.KeeperState.Expired) {
                    System.out.println("超时了");
                } else if (watchedEvent.getState() == Event.KeeperState.AuthFailed) {
                    System.out.println("认证失败!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

测试
在这里插入图片描述
在这里插入图片描述

可以看出当监听到/config/mysql/username节点的数据发生变更时,控制台就会重新获取节点值

如果控制台出现了ConnectionLoss错误,可能是网络差导致连接断开或者服务器宕机

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thecoastlines

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值