zookeeper实现配置中心
来源:互联网 发布:python cnn 代码下载 编辑:程序博客网 时间:2024/06/05 11:05
最近做新系统,搞了个配置中心。本地用ehcache,配置最终存储在zookeeper上。系统启动连接zk,检查指定节点目录是否存在。若不存在,则创建。随后设置监听。节点内容变化则触发监听程序,更新数据到本地缓存。读数据时本地缓存不命中,则读取zk对应路径节点内容到本地。
相关代码示例如下:
1.连接zk逻辑
private static ZooKeeper getInstance(){ if (zooKeeper == null) { try { if (INSTANCE_INIT_LOCK.tryLock(2, TimeUnit.SECONDS)) { try { zooKeeper = new ZooKeeper(Environment.ZK_ADDRESS, 20000, null); // init cfg root path ConfZkClient.createWithParent(Environment.CONF_DATA_PATH); zooKeeper.register(new Watcher() { @Override public void process(WatchedEvent watchedEvent) { try { logger.info("confcenter: watcher:{}", watchedEvent); // session expire, close old and create new if (watchedEvent.getState() == Event.KeeperState.Expired) { zooKeeper.close(); zooKeeper = null; getInstance(); } String path = watchedEvent.getPath(); String key = pathToKey(path); if (key != null) { // add One-time trigger zooKeeper.exists(path, true); if (watchedEvent.getType() == Event.EventType.NodeDeleted) { ConfClient.remove(key); } else if (watchedEvent.getType() == Event.EventType.NodeDataChanged) { String data = getPathDataByKey(key); ConfClient.update(key, data); } } } catch (KeeperException e) { logger.error("confcenter KeeperException:"+ e.getMessage(), e); } catch (InterruptedException e) { logger.error("confcenter InterruptedException:" +e.getMessage(), e); } } }); } finally { INSTANCE_INIT_LOCK.unlock(); } } } catch (InterruptedException e) { logger.error("confcenter init InterruptedException!" + e.getMessage(), e); } catch (IOException e) { logger.error("confcenter init IOException!" + e.getMessage(), e); } } if (zooKeeper == null) { throw new NullPointerException("confcenter ConfZkClient.zooKeeper is null."); } return zooKeeper;}
2.重新初始化置加载逻辑
public class ConfPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer { private static Logger log = LoggerFactory.getLogger(ConfPropertyPlaceholderConfigurer.class); private String beanName; private BeanFactory beanFactory; /** * @param beanFactoryToProcess * @param props * @throws BeansException */ @Override protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { // 初始化StringValueResolver StringValueResolver valueResolver = new StringValueResolver() { String placeholderPrefix = "${"; String placeholderSuffix = "}"; @Override public String resolveStringValue(String strVal) { StringBuffer buf = new StringBuffer(strVal); // 如果value值匹配'${***}' boolean start = strVal.startsWith(placeholderPrefix); boolean end = strVal.endsWith(placeholderSuffix); while (start && end) { // 替换value值,${***} -> ***,例如${default.key01} -> default.key01 String key = buf.substring(placeholderPrefix.length(), buf.length() - placeholderSuffix.length()); // 获取value,从properties、cache、zookeeper String zkValue = ConfClient.get(key, ""); buf = new StringBuffer(zkValue); start = buf.toString().startsWith(placeholderPrefix); end = buf.toString().endsWith(placeholderSuffix); } return buf.toString(); } }; // init bean define visitor BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver); // 获取所有的bean定义,替换占位符 String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames(); if (beanNames != null && beanNames.length > 0) { for (String beanName : beanNames) { if (!(beanName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) { BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanName); visitor.visitBeanDefinition(bd); } } } }
3.EhCache逻辑
public class ConfClient { private static Logger logger = LoggerFactory.getLogger(ConfClient.class); public static Properties localProp = PropertiesUtil.loadProperties("confcenter.properties"); private static Cache cache; static { // default use ehcche.xml under src CacheManager manager = CacheManager.create(); /** * name:缓存名称 * maxElementsInMemory:缓存最大个数 * overflowToDisk:当内存中对象数量达到maxElementsInMemory时,ehcache将会对象写到磁盘中。 * eternal:对象是否永久有效,一但设置了,timeout将不起作用。 * timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大 * timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 * */ cache = new Cache(Environment.CONF_DATA_PATH, 10000, false, true, 1800, 1800); manager.addCache(cache); } /** * 初始化配置 * * @param key * @param value */ public static void set(String key, String value) { if (cache != null) { logger.info("初始化配置: [{}:{}]", new Object[]{key, value}); cache.put(new Element(key, value)); } } /** * 更新配置 * * @param key * @param value */ public static void update(String key, String value) { if (cache != null) { if (cache.get(key)!=null) { logger.info("更新配置: [{}:{}]", new Object[]{key, value}); cache.put(new Element(key, value)); } } } /** * 获取配置 * * @param key * @param defaultVal * @return */ public static String get(String key, String defaultVal) { if (localProp != null && localProp.containsKey(key)) { return localProp.getProperty(key); } if (cache != null) { Element element = cache.get(key); if (element != null) { return (String) element.getObjectValue(); } } String zkData = ConfZkClient.getPathDataByKey(key); if (zkData != null) { set(key, zkData); return zkData; } return defaultVal; } /** * 删除配置 * * @param key * @return */ public static boolean remove(String key) { if (cache != null) { logger.info("删除配置:key ", key); return cache.remove(key); } return false; }}
阅读全文
0 0
- zookeeper实现配置中心
- zookeeper配置中心的实现
- 基于zookeeper的配置中心
- zookeeper 注册中心安装配置
- ZooKeeper 学习 (六) ZooKeeper实现数据发布订阅(即配置中心)
- 基于zookeeper的分布式一致性配置中心
- SpringCloud用zookeeper搭建配置中心
- SpringBoot+ZooKeeper+ZKUI+Drools 实现应用配置中心及业务规则动态加载
- zookeeper实现注册中心(demo)
- zookeeper(二) 数据发布与订阅(配置中心)
- dubbo注册中心zookeeper的安装与配置
- 用Zookeeper作为Spring cloud的配置中心
- Spring Cloud 中使用zookeeper作为服务注册中心与配置中心
- Zookeeper 注册中心解析
- zookeeper注册中心解析
- Zookeeper注册中心解析
- Zookeeper 注册中心解析
- Zookeeper 注册中心解析
- linux系统mysql 查看当前使用的配置文件my.cnf的方法
- linux常用命令整理
- python 多线程问题
- Ambari Atlas安装配置
- Springmvc 跨域请求
- zookeeper实现配置中心
- getInputStream/getReader() has already been called for this request
- 创建Library 并 引用
- 【vue+axios】一个项目学会前端实现登录拦截
- 实用!Bootstrap4(纯手工翻译)一次重大更新几乎涉及每行代码
- Scanner答疑
- NYOJ23 取石子(一)(详解巴什博奕)
- 史上最简单的 MySQL 教程(三十七)
- iOS开发-关于Super的题目