第6章:基于zookeeper的配置管理中心
第6章:基于zookeeper的配置管理中心
·
1、使用场景
配置中心一般用作系统的参数配置,它需要满足如下几个要求:高效获取、实时感知、分布式访问。对于一些少量频次访问的场景我们可以使用mysql数据库实现,但是有些参数在系统中访问频次较高,甚至是接口每访问一次就需要调起获取一次,特别在是大规模系统访问量的情况下,我们就需要一个高效获取实时感知的分布式配置中心。本章节我们使用zookeeper来实现一个分布式配置管理中心组件。
2、实现逻辑
实现的架构图如下所示,采取数据加载到内存方式解决高效获取的问题,借助zookeeper的节点监听机制来实现实时感知。
实现的逻辑流程图如下:分为新增配置,获取配置,删除配置。修改配置和删除配置的逻辑是一致的。
3、代码实现
接入层的接口定义如下:/**
*
*/
package com.flykingmz.zookeeper.configyard;
import java.util.Map;
/**
* 配置资源接口
* @author flyking
*
*/
public interface ConfigYard {
/**
* 配置平台根节点名称
*/
static String yardRoot = "/yard";
/**
* 初始化配置
*/
void init();
/**
* 重新加载配置资源
*/
void reload();
/**
* 添加配置
* @param key
* @param value
*/
void add(String key, String value);
/**
* 更新配置
* @param key
* @param value
*/
void update(String key, String value);
/**
* 删除配置
* @param key
*/
void delete(String key);
/**
* 获取配置
* @param key
* @return
*/
String get(String key);
/**
* 获取所有的配置内容
* @return
*/
Map<String, String> getAll();
}
接口一个实现类:
/**
*
*/
package com.flykingmz.zookeeper.configyard;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.I0Itec.zkclient.ZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author flyking
*
*/
public class ProgrammaticallyConfigYard implements ConfigYard {
private final static Logger logger = LoggerFactory
.getLogger(ProgrammaticallyConfigYardTest.class);
/**
* 存储配置内容
*/
private volatile Map<String, String> yardProperties = new HashMap<String, String>();
private ZkClient client;
private ConfigYardWatcher configYardWatcher;
public ProgrammaticallyConfigYard(String serverstring) {
this.client = new ZkClient(serverstring);
configYardWatcher = new ConfigYardWatcher(client,this);
this.init();
}
/**
* 初始化加载配置到内存
*/
public void init() {
if(!client.exists(yardRoot)){
client.createPersistent(yardRoot);
}
if (yardProperties == null) {
logger.info("start to init yardProperties");
yardProperties = this.getAll();
logger.info("init yardProperties over");
}
}
private String contactKey(String key){
return yardRoot.concat("/").concat(key);
}
public void add(String key, String value) {
String contactKey = this.contactKey(key);
this.client.createPersistent(contactKey, value);
configYardWatcher.watcher(contactKey);
}
public void update(String key, String value) {
String contactKey = this.contactKey(key);
this.client.writeData(contactKey, value);
configYardWatcher.watcher(contactKey);
}
public void delete(String key) {
String contactKey = this.contactKey(key);
this.client.delete(contactKey);
}
public String get(String key) {
if(this.yardProperties.get(key) == null){
String contactKey = this.contactKey(key);
if(!this.client.exists(contactKey)){
return null;
}
return this.client.readData(contactKey);
}
return yardProperties.get(key);
}
public Map<String, String> getAll() {
if(yardProperties != null){
return yardProperties;
}
List<String> yardList = this.client.getChildren(yardRoot);
Map<String, String> currentYardProperties = new HashMap<String, String>();
for(String yard : yardList){
String value = this.client.readData(yard);
String key = yard.substring(yard.indexOf("/")+1);
currentYardProperties.put(key, value);
}
return yardProperties;
}
public void reload() {
List<String> yardList = this.client.getChildren(yardRoot);
Map<String, String> currentYardProperties = new HashMap<String, String>();
for(String yard : yardList){
String value = this.client.readData(this.contactKey(yard));
currentYardProperties.put(yard, value);
}
yardProperties = currentYardProperties;
}
}
在其中使用到的一个zookeeper的监听实现类:
/**
*
*/
package com.flykingmz.zookeeper.configyard;
import java.util.List;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author flyking
*
*/
public class ConfigYardWatcher {
private final static Logger logger = LoggerFactory
.getLogger(ConfigYardWatcher.class);
private ZkClient client;
private ConfigYardListener configYardListener;
private ConfigYard configYard;
public ConfigYardWatcher(ZkClient client,ConfigYard configYard) {
this.client = client;
this.configYard = configYard;
this.initConfigYard();
}
private void initConfigYard(){
configYardListener = new ConfigYardListener();
}
public void watcher(String key){
client.subscribeDataChanges(key, configYardListener);
client.subscribeChildChanges(key, configYardListener);
}
/**
* 配置监听器
* @author flyking
*
*/
private class ConfigYardListener implements IZkDataListener,IZkChildListener{
public void handleDataChange(String dataPath, Object data)
throws Exception {
logger.info("data {} change,start reload configProperties",dataPath);
configYard.reload();
}
public void handleDataDeleted(String dataPath) throws Exception {
logger.info("data {} delete,start reload configProperties",dataPath);
configYard.reload();
}
public void handleChildChange(String parentPath,
List<String> currentChilds) throws Exception {
logger.info("data {} ChildChange,start reload configProperties",parentPath);
configYard.reload();
}
}
}
基于实现类的一个测试代码:
/**
*
*/
package com.flykingmz.zookeeper.configyard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author flyking
*
*/
public class ProgrammaticallyConfigYardTest {
private final static Logger logger = LoggerFactory
.getLogger(ProgrammaticallyConfigYard.class);
public static void main(String[] args) {
ProgrammaticallyConfigYard yard = new ProgrammaticallyConfigYard("host:port");
yard.add("testKey1", "1");
yard.add("testKey2", "2");
yard.add("testKey3", "3");
yard.add("testKey4", "4");
yard.add("testKey5", "5");
yard.add("testKey6", "6");
logger.info("value is===>"+yard.get("testKey1"));
logger.info("value is===>"+yard.get("testKey2"));
logger.info("value is===>"+yard.get("testKey3"));
logger.info("value is===>"+yard.get("testKey4"));
logger.info("value is===>"+yard.get("testKey5"));
logger.info("value is===>"+yard.get("testKey6"));
yard.update("testKey6", "testKey6");
logger.info("update testKey6 value is===>"+yard.get("testKey6"));
yard.delete("testKey1");
yard.delete("testKey2");
yard.delete("testKey3");
yard.delete("testKey4");
yard.delete("testKey5");
yard.delete("testKey6");
}
}
测试结果如下:
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - value is===>1
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - value is===>2
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - value is===>3
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - value is===>4
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - value is===>5
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - value is===>6
2016-10-26 14:58:39 [ZkClient-EventThread-9-172.16.10.58:2181] INFO com.flykingmz.zookeeper.configyard.ConfigYardWatcher - data /yard/testKey6 change,start reload configProperties
2016-10-26 14:58:39 [main] INFO com.flykingmz.zookeeper.configyard.ProgrammaticallyConfigYard - update testKey6 value is===>testKey6
2016-10-26 14:58:39 [ZkClient-EventThread-9-172.16.10.58:2181] INFO com.flykingmz.zookeeper.configyard.ConfigYardWatcher - data /yard/testKey6 delete,start reload configProperties
更多推荐
已为社区贡献5条内容
所有评论(0)