为什么要用统一配置?

我们做项目时用到的配置比如数据库配置等...我们都是写死在项目里面,如果需要更改,那么也是的修改配置文件然后再投产上去,那么问题来了,如果做集群的呢,有100台机器,这时候做修改那就太不切实际了;那么就需要用到统一配置管理啦。

解决思路

1.把公共配置抽取出来

2.对公共配置进行维护

3.修改公共配置后应用不需要重新部署

采用方案

1.公共配置抽取存放于zookeeper中并落地数据库

2.对公共配置修改后发布到zookeeper中并落地数据库

3.对应用开启配置实时监听,zookeeper配置文件一旦被修改,应用可实时监听到并获取

下面基于zookeeper粗略实现了一个统一配置管理

需要用到的jar是zkclient配置文件Config

package com.cwh.zk.util;
 
import java.io.Serializable;
 
public class Config implements Serializable{
 
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String userNm;
	private String userPw;
	
	public Config() {
	}
	public Config(String userNm, String userPw) {
		this.userNm = userNm;
		this.userPw = userPw;
	}
	public String getUserNm() {
		return userNm;
	}
	public void setUserNm(String userNm) {
		this.userNm = userNm;
	}
	public String getUserPw() {
		return userPw;
	}
	public void setUserPw(String userPw) {
		this.userPw = userPw;
	}
	@Override
	public String toString() {
		return "Config [userNm=" + userNm + ", userPw=" + userPw + "]";
	}
	
}复制代码

 配置管理中心ZkConfigMag 

package com.cwh.zk.util;
 
import org.I0Itec.zkclient.ZkClient;
 
public class ZkConfigMag {
 
	private Config config;
	/**
	 * 从数据库加载配置
	 */
	public Config downLoadConfigFromDB(){
		//getDB
		config = new Config("nm", "pw");
		return config;
	}
	
	/**
	 * 配置文件上传到数据库
	 */
	public void upLoadConfigToDB(String nm, String pw){
		if(config==null)config = new Config();
		config.setUserNm(nm);
		config.setUserPw(pw);
		//updateDB
	}
	
	/**
	 * 配置文件同步到zookeeper
	 */
	public void syncConfigToZk(){
		ZkClient zk = new ZkClient("localhost:2181");
		if(!zk.exists("/zkConfig")){
			zk.createPersistent("/zkConfig",true);
		}
		zk.writeData("/zkConfig", config);
		zk.close();
	}
}
复制代码

应用监听实现ZkGetConfigClient 

package com.cwh.zk.util;
 
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
 
public class ZkGetConfigClient {
 
	private Config config;
 
	public Config getConfig() {
		ZkClient zk = new ZkClient("localhost:2181");
		config = (Config)zk.readData("/zkConfig");
		System.out.println("加载到配置:"+config.toString());
		
		//监听配置文件修改
		zk.subscribeDataChanges("/zkConfig", new IZkDataListener(){
			@Override
			public void handleDataChange(String arg0, Object arg1)
					throws Exception {
				config = (Config) arg1;
				System.out.println("监听到配置文件被修改:"+config.toString());
			}
 
			@Override
			public void handleDataDeleted(String arg0) throws Exception {
				config = null;
				System.out.println("监听到配置文件被删除");
			}
			
		});
		return config;
	}
	public static void main(String[] args) {
		ZkGetConfigClient client = new ZkGetConfigClient();
		client.getConfig();
		System.out.println(client.config.toString());
		for(int i = 0;i<10;i++){
			System.out.println(client.config.toString());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
 
	
}复制代码

 测试,启动配置管理中心 

package com.cwh.zkConfig.test;
 
import com.cwh.zk.util.Config;
import com.cwh.zk.util.ZkConfigMag;
 
public class ZkConfigTest {
 
	public static void main(String[] args) {
		ZkConfigMag mag = new ZkConfigMag();
		Config config = mag.downLoadConfigFromDB();
		System.out.println("....加载数据库配置...."+config.toString());
		mag.syncConfigToZk();
		System.out.println("....同步配置文件到zookeeper....");
		
		//歇会,这样看比较清晰
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		mag.upLoadConfigToDB("cwhcc", "passwordcc");
		System.out.println("....修改配置文件...."+config.toString());
		mag.syncConfigToZk();
		System.out.println("....同步配置文件到zookeeper....");
		
		
	}
	
}
复制代码

测试结果: 


配置管理中心打印