ZooKeeper实践:(2)配置管理
一、 前言
配置是每个程序不可或缺的一部分,配置有多重方式:xml、ini、property、database等等,从最初的单机环境到现在的分布式环境。
1. 以文件的格式存储配置,修改任何都要改程序,重新发布,重新部署,经常出现数据不一致的问题,配置错误,会造成更大的问题。
2. 以数据库+缓存配置,解决了动态更新配置的方式,但是存在数据库的单点问题,一单数据库出现问题,更新的操作都会失败,造成配置不能持久化。
随着机器数的增多,逐个修改配置是一件不合理的做法,使用Zookeeper可以实现数据发布与订阅,顾名思义就是把数据存储在Zookeeper的节点上,供订阅方进行获取,实现配置信息的集中式管理和动态更新。解决以上问题
二、需求
1. 实现集中式配置管理
2. 实现灰度发布(先发布一台机器)
三、技术原理
1. 配置信息存储在Zookeeper的某个目录下中,目录的命名按照一定的规则(例如:应用ID),一组相同功能的应用集群监控一个节点。
2. 配置发生变化,应用服务器会监听到事件,然后从Zookeeper获取新的配置信息到更新应用服务器的本地缓存中。
3. 做一个简单的界面展示集群的所有机器,可以拉出来一台灰度发布。
4. 应用服务器在接收到新的配置信息时判断是否是灰度发布的,如果是判断机器的IP,如果IP相同就更新本地缓存,否则不更新。
四:架构体系
五:流程图
六:相关代码
client模拟:
package com.zk.config.manager; import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState; public class App {
private CountDownLatch connectedSemaphore = new CountDownLatch(1);
private ZooKeeper zooKeeper;
private Object lock = new Object();
private String ip; private String rootConfig; public App(String ip, String root) {
this.ip = ip;
this.rootConfig = root;
this.zooKeeper = connectZookeeper(); }
/**
* 更新缓存
* @param path
* @param value
*/ private void updateCache(String path, String value) {
//System.out.println(CacheManager.get("ips"));
if (CacheManager.get("ips").contains(this.ip)) {
CacheManager.add(this.ip + path, value);
System.out.println(ip+"被更新了");
}
} public ZooKeeper connectZookeeper() {
synchronized (lock) {
if (zooKeeper == null) {
try {
zooKeeper = new ZooKeeper("192.168.1.222:2181", 5000, new Watcher() {
public void process(WatchedEvent event) {
if (KeeperState.SyncConnected == event.getState()) {
if (EventType.None == event.getType() && null == event.getPath()) {
try {
connectedSemaphore.countDown();
zooKeeper.getChildren(rootConfig, true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (EventType.NodeChildrenChanged == event.getType()) {
try {
System.out.println(ip);
String path = event.getPath();
String value =new String(zooKeeper.getData(path, false, null));
zooKeeper.getChildren(rootConfig, true);
updateCache(path,value);//模拟更新缓存
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} } }
}
} );
connectedSemaphore.await();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
return zooKeeper;
}
}
本地缓存模拟:
package com.zk.config.manager; import java.util.HashMap;
import java.util.Map; //模拟本机缓存
public class CacheManager { private static Map<String, String> map = new HashMap<String, String>(); public static void add(String key,String value)
{
map.put(key, value);
} public static String get(String key)
{
return map.get(key);
} }
配置管理模拟:
package com.zk.config.manager; import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper; public class ConfigManager { private static String rootConfigName = "/testApp";
public static void main(String[] args) throws KeeperException, InterruptedException { String ips = args[0]; // 要发布的机器IP
CacheManager.add("ips", ips);
App app1 = new App("192.168.1.1", rootConfigName);
App app2 = new App("192.168.1.2", rootConfigName);
App app3 = new App("192.168.1.3", rootConfigName);
ZooKeeper zooKeeper = app1.connectZookeeper();
zooKeeper.create(rootConfigName + "/gggggg", "sds".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.delete(rootConfigName + "/gggggg", -1);
Thread.sleep(60000); }
}
运行结果:
192.168.1.3
192.168.1.1
192.168.1.2
192.168.1.1被更新了
ZooKeeper实践:(2)配置管理的更多相关文章
- ZooKeeper实践:(1)配置管理
一. 前言 配置是每个程序不可或缺的一部分,配置有多重方式:xml.ini.property.database等等,从最初的单机环境到现在的分布式环境. 1. 以文件的格式存储配置,修改任何都 ...
- Zookeeper实践方案:(4)命名服务
1.基本介绍 命名服务是指通过指定的名字来获取资源或者服务的地址,提供者的信息.利用Zookeeper非常easy创建一个全局的路径,而这个路径就能够作为一个名字.它能够指向集群中的集群.提供的服务的 ...
- ZooKeeper实践方案:(7) 分布式锁
1.基本介绍 分布式锁是控制分布式系统之间同步訪问共享资源的一种方式,须要相互排斥来防止彼此干扰来保证一致性. 利用Zookeeper的强一致性能够完毕锁服务.Zookeeper的官方文档是列举了两种 ...
- ZooKeeper实践:(2)集群管理
前言: 随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机 ...
- ZooKeeper实践:(1)集群管理
前言: 随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机 ...
- 部署zookeeper实践
1.解压zookeeper 2.环境变量设置 hadoop@namenode:~/zookeeper-3.4.6/conf$ sudo vim /etc/profile export JAVA_HOM ...
- 分布式锁 ----zookeeper实践 (排它锁)
排它锁概念: Exclusive Locks,被称为X锁,写锁,独占锁.如果事物T1对数据对象O1加上了排它锁,那么在整个加锁期间,只允许事务T1对O1进行读写操作,其他事务必须等到T1释放锁后才能进 ...
- 1、ZooKeeper 基本概念、使用方法、实践场景
ZooKeeper 基本概念 ZooKeeper 是面向分布式应用的协调服务,其实现了树形结构的数据模型(与文件系统类似),并且提供了简洁的编程原语.ZooKeeper 能够作为基础,用于构建更高层级 ...
- Disconf实践指南:安装篇
Disconf是百度开源出来的一款基于Zookeeper的分布式配置管理软件.目前很多公司都在使用,包括滴滴.百度.网易.顺丰等公司.通过简单的界面操作就可以动态修改配置属性,还是很方便的.使用Dis ...
随机推荐
- python基础之02列表/元组/字典/set集合
python中内置的数据类型有列表(list)元组(tuple)字典(directory). 1 list list是一种可变的有序的集合.来看一个list实例: #第一种方法: >>&g ...
- K8S发布解释型语言应用的最佳实践
说明 我们知道,k8s在发布编译型语言的应用时,几乎不用多考虑,就会选择将编译好jar/war包(java语言)或者二进制文件(golang/c++)直接打到镜像当中,生成新的应用镜像,然后将镜像推到 ...
- 关于RESTful的理解
如何更好的理解RESTful? (转自https://sanwen8.cn/p/54czrEO.html) 在测试开发中,我们经常接触到API,在调用API时候特别是第三方API时候,我们常常陷入以下 ...
- ICPC 2015 Shenyang Online-E-EXCITED DATAbase
题目描述 She says that any Pavarotti among the nightingales will serenade his mate while she sits on her ...
- The Difference Between Big Data and a Lot of Data
The Difference Between Big Data and a Lot of Data The term “big data” has been around for a while no ...
- <!DOCTYPE>是干嘛用的?— html文档类型
一.啥是文档类型? 在网站开发中一定遇到过这样几种html文档 <!DOCTYPE> 是啥? Web 世界中存在许多不同的文档.只有了解文档的类型,浏览器才能正确地显示文档. HTML 也 ...
- HDU 4500 小Q系列故事——屌丝的逆袭
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4500 解题报告:简单题,数据范围不大,直接暴力每个点,然后再比较出得分最大的点的位置和分数. #inc ...
- nginx配置php时fastcgi_pass参数问题
更多内容推荐微信公众号,欢迎关注: 在配置nginx的时候,fastcgi_pass的配置问题,如下所示: location ~ \.php$ { root /home/wwwroot; fastcg ...
- Linux/Unix系统编程手册 第一章:历史和标准
Unix的开发不受控于某一个厂商或者组织,是由诸多商业和非商业团体共同贡献进行演化的.这导致两个结果:一是Unix集多种特性于一身,二是由于参与者众多,随着时间推移,Unix实现方式逐渐趋于分裂. 由 ...
- Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理
在做Android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map<String ...