Zookeeper(3)-使用ZooKeeper作爲配置中心

ZooKeeper作爲配置中心

現在我們大多數應用都是採用的是分佈式開發的應用,搭建到不同的服務器上,我們的配置文件,同一個應用程序的配置文件一樣,還有就是多個程序存在相同的配置。當我們配置文件中有個配置屬性需要改變,我們需要改變每個程序的配置屬性,這樣會很麻煩的去修改配置。而現在可以使用SpringCloud提供的配置中心,或者使用zookeeper來實現配置中心。

如何使用Zookeeper作爲配置中心?

我們可以清除的瞭解ZooKeeper的Znode節點提供了一個Watcher,我們可以通過該方法來實現配置改變,來通知所有客戶端配置的變化,並賦值。

如何存儲配置信息呢

其實我們可以把key作爲znode的節點名稱,value則可以使用znode的數據域來儲存,從而達成一個key-value的形式來存儲配置信息。

下面是Zookeeper作爲配置中心的代碼

  1. ConfigServer主要是對配置的讀取,配置信息的寫入,獲取全部配置信息

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ConfigServer extends ConnectWatcher{
    private String rootPath="/config";
    public ConfigServer(){
        this.connect();
    }
    //寫入配置信息
    public void write(String key,String value){
        try {
            Stat stat=this.zooKeeper.exists(rootPath+"/"+key,false);
            if(stat!=null){
                this.zooKeeper.setData(rootPath+"/"+key,value.getBytes(),-1);
            }else{
                this.zooKeeper.create(rootPath+"/"+key,value.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public Map<String,String> getAllConfig(){
        Map<String,String> resultMap=new HashMap<String, String>();
        try {
            List<String> paths=this.zooKeeper.getChildren(rootPath,false);
            for (String path:paths
                 ) {
                System.out.println(path);
                String value=new String(this.zooKeeper.getData(rootPath+"/"+path,false,null));
                resultMap.put(path,value);
            }
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return resultMap;
    }
    public void createRoot(){
        try {
            this.zooKeeper.create("/config",null, ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public String readConfig(String key, Watcher watcher){
        byte[] bytes=null;
        try {
            bytes=this.zooKeeper.getData(rootPath+"/"+key,watcher,null);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new String(bytes);
    }

}
  1. configClient主要是相當於我們每臺服務器上對於配置中心的配置屬性的監控
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

public class ConfigClient implements Watcher {
    private ConfigServer configServer=new ConfigServer();
    private CountDownLatch countDownLatch=new CountDownLatch(1);
    public void process(WatchedEvent watchedEvent) {
        String path=watchedEvent.getPath();
        if(watchedEvent.getType()== Event.EventType.NodeDataChanged){
            this.updateConfig(path);
        }
    }
    public void updateConfig(String path){

        System.out.println(configServer.readConfig(path.substring(path.lastIndexOf("/")+1),this));
    }
    public void getAllConfig(){
        Map<String,String> map=configServer.getAllConfig();
        Iterator<String> keys=map.keySet().iterator();
        while (keys.hasNext()){
            String key=keys.next();
            String value=map.get(key);
            System.out.println("key:"+key+"  value:"+value);
        }
    }

}
  1. connectWatcher主要是用來創建ZK的連接及關閉
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;

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

public class ConnectWatcher  implements Watcher{
    private final static String ZK_HOST="47.106.132.60:2181,47.106.132.60:2182,47.106.132.60:2183";
    private final static int SESSION_TIME_OUT=3000;
    private CountDownLatch countDownLatch=new CountDownLatch(1);
    ZooKeeper zooKeeper;
    public void process(WatchedEvent watchedEvent) {
        if(watchedEvent.getState()== Event.KeeperState.SyncConnected){
            countDownLatch.countDown();
        }
    }
    public void connect(){
        try {
            zooKeeper=new ZooKeeper(ZK_HOST,SESSION_TIME_OUT,this);
            countDownLatch.await();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void close(){
        try {
            this.zooKeeper.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
  1. 測試類
import org.junit.Test;

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) {
        CountDownLatch countDownLatch=new CountDownLatch(1);
        ConfigClient configClient=new ConfigClient();
        configClient.updateConfig("jdbc.url");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void addConfig(){
        ConfigServer configServer=new ConfigServer();
        configServer.createRoot();
        configServer.write("jdbc.url","com.mysql.jdbc.Driver");
        configServer.write("jdbc.password","1234");
        configServer.close();
    }
    @Test
    public void updateConfig(){
        ConfigServer configServer=new ConfigServer();
        configServer.write("jdbc.url","com.mysql.jdbc.update.test2");
        configServer.close();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章