Zookeeper系列(三十)Zookeeper场景应用之配置管理中心
来源:互联网 发布:包小姐过夜 知乎 编辑:程序博客网 时间:2024/05/23 16:10
1、使用场景
配置中心一般用作系统的参数配置,它需要满足如下几个要求:高效获取、实时感知、分布式访问。对于一些少量频次访问的场景我们可以使用mysql数据库实现,但是有些参数在系统中访问频次较高,甚至是接口每访问一次就需要调起获取一次,特别在是大规模系统访问量的情况下,我们就需要一个高效获取实时感知的分布式配置中心。本章节我们使用zookeeper来实现一个分布式配置管理中心组件。
2、实现逻辑
实现的架构图如下所示,采取数据加载到内存方式解决高效获取的问题,借助zookeeper的节点监听机制来实现实时感知。
实现的逻辑流程图如下:分为新增配置,获取配置,删除配置。修改配置和删除配置的逻辑是一致的。
3、代码实现
接入层的接口定义如下:-
-
-
- package com.flykingmz.zookeeper.configyard;
-
- import java.util.Map;
-
-
-
-
-
-
- public interface ConfigYard {
-
-
-
- static String yardRoot = "/yard";
-
-
-
-
- void init();
-
-
-
-
- void reload();
-
-
-
-
-
-
- void add(String key, String value);
-
-
-
-
-
-
- void update(String key, String value);
-
-
-
-
-
- void delete(String key);
-
-
-
-
-
-
- String get(String key);
-
-
-
-
-
- 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;
-
-
-
-
-
- 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;
-
-
-
-
-
- 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);
- }
-
-
-
-
-
-
- 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;
-
-
-
-
-
- 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
本系统的实现源码可以从https://github.com/flykingmz/zookeeper-step获取,具体的项目名称为:configYard
0 0