IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Zookeeper实现配置中心 -> 正文阅读

[大数据]Zookeeper实现配置中心

Zookeeper实现配置中心

一、环境准备

1 . 准备集群

搭建Zookeeper集群,我准备了四服务,分别是192.168.91.129,192.168.91.130, 192.168.91.131, 192.168.91.132,我本地用虚拟机开的四台机器,家里有条件的可以直接搞几台阿里云服务器,其实一台机器也能搞,推荐用三台服务器

2 . 导入依赖(客户端版本和Server端版本保持一致)

  <dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.6.3</version>
  </dependency>

二、实现思路

1 . 创建Zookeeper对象(利用门栓保证zk可用)
2 . 判断配置中心的节点是否存在(使用回调的方式,需要传递 watch和statWatch),然后阻塞线程,直到获取配置完成
3 . 几种情况

  1. 第一个分支【没有配置文件节点】:如果没有配置文件节点,那需要在exists的Watch中对event时间Type中NodeCreated进行处理(一旦配置文件创建了就会回调这个地方),处理无非就是去get配置节点
  2. 第二个分支【有配置文件】:这个是正常流程用getData把节点数据读取回来(需要传递Watch监控后续更新)
  3. 第三个分支【配置文件更新】:getData的时候传递Watch对后续一些操作进行了监听,如果配置文件更新需要重新getData
  4. 第四个分支【配置节点删除】:这个地方有处理的方式比较宽泛,如果要求配置文件节点被删除了,配置一定也要同步删除,强一致要求配置和节点同步,那就需要清空配置文件,并且重新阻塞,重新getData,如果没有这种需求那这里就看着处理就行了(毕竟谁没事会删除配置文件呢)

三、代码实现

1 . Test测试

package org.example.configdemo2;

import org.apache.zookeeper.ZooKeeper;
import org.example.congfig.MyConf;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

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

/**
 * @author chao
 */
public class TestMain {

    /**
     * zk
     */
    private ZooKeeper zk;

    /**
     * 门栓
     */
    private final CountDownLatch countDownLatch = new CountDownLatch(1);

    @Before
    public void connection() {
        try {
            zk = new ZooKeeper("192.168.91.129,192.168.91.130,192.168.91.131,192.168.91.132/configTestdemo", 1000, event -> {
                switch (event.getState()) {
                    case Unknown:
                        break;
                    case Disconnected:
                        break;
                    case NoSyncConnected:
                        break;
                    case SyncConnected:
                        System.out.println("zk connection success !!");
                        countDownLatch.countDown();
                        break;
                    case AuthFailed:
                        break;
                    case ConnectedReadOnly:
                        break;
                    case SaslAuthenticated:
                        break;
                    case Expired:
                        break;
                    case Closed:
                        break;
                    default:
                }
            });
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @After
    public void close() {
        try {
            zk.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void show() {
        WatchAndCallback watchAndCal = new WatchAndCallback(zk);
        MyConf conf = watchAndCal.getConf();
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String config = conf.getConfig();
            if(config == null || "".equals(config)){
                conf = watchAndCal.getConf();
            }
            System.out.println(config);
        }
    }
}

2 . WatchAndCallback类(一个工具类)

package org.example.configdemo2;

import lombok.Data;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.example.congfig.MyConf;

import java.util.concurrent.CountDownLatch;

/**
 * @author chao
 */
@Data
public class WatchAndCallback implements Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback {

    /**
     * zk
     */
    private ZooKeeper zk;

    /**
     * myConf
     */
    private MyConf myConf = new MyConf();

    /**
     * pathNode
     */
    public static final String PATH_NODE = "/cnf";

    /**
     * 门栓
     */
    private CountDownLatch countDownLatch = new CountDownLatch(1);

    /**
     * 构造
     *
     * @param zk zk
     */
    public WatchAndCallback(ZooKeeper zk) {
        this.zk = zk;
    }

    @Override
    public void process(WatchedEvent event) {
        switch (event.getType()) {
            case None:
                break;
            case NodeCreated:
                zk.getData(PATH_NODE, this, this, "get");
                break;
            case NodeDeleted:
                myConf.setConfig("");
                countDownLatch = new CountDownLatch(1);
                System.out.println("配置删除,阻塞等待... ...");
                zk.getData(PATH_NODE, this, this, "get");
                break;
            case NodeDataChanged:
                zk.getData(PATH_NODE, this, this, "get");
                break;
            case NodeChildrenChanged:
                break;
            case DataWatchRemoved:
                break;
            case ChildWatchRemoved:
                break;
            case PersistentWatchRemoved:
                break;
            default:
        }
    }

    public MyConf getConf() {
        zk.exists(PATH_NODE, this, this, "exists");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return myConf;
    }

    @Override
    public void processResult(int rc, String path, Object ctx, Stat stat) {
        // stat callback
        if (stat != null) {
            zk.getData(PATH_NODE, this, this, "get");
        }
    }

    @Override
    public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
        if (stat != null) {
            myConf.setConfig(new String(data));
            countDownLatch.countDown();
        }
    }
}

四、测试结果

在这里插入图片描述

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 15:49:12  更:2021-12-23 15:51:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:36:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码