Zookeeper(3)-使用ZooKeeper作為配置中心
阿新 • • 發佈:2019-02-01
ZooKeeper作為配置中心
現在我們大多數應用都是採用的是分散式開發的應用,搭建到不同的伺服器上,我們的配置檔案,同一個應用程式的配置檔案一樣,還有就是多個程式存在相同的配置。當我們配置檔案中有個配置屬性需要改變,我們需要改變每個程式的配置屬性,這樣會很麻煩的去修改配置。而現在可以使用SpringCloud提供的配置中心,或者使用zookeeper來實現配置中心。
如何使用Zookeeper作為配置中心?
我們可以清除的瞭解ZooKeeper的Znode節點提供了一個Watcher,我們可以通過該方法來實現配置改變,來通知所有客戶端配置的變化,並賦值。
如何儲存配置資訊呢
其實我們可以把key作為znode的節點名稱,value則可以使用znode的資料域來儲存,從而達成一個key-value的形式來儲存配置資訊。
下面是Zookeeper作為配置中心的程式碼
- 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);
}
}
- 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);
}
}
}
- 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();
}
}
}
- 測試類
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();
}
}