一、 前言

    配置是每个程序不可或缺的一部分,配置有多重方式: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)配置管理的更多相关文章

  1. ZooKeeper实践:(1)配置管理

    一. 前言     配置是每个程序不可或缺的一部分,配置有多重方式:xml.ini.property.database等等,从最初的单机环境到现在的分布式环境. 1. 以文件的格式存储配置,修改任何都 ...

  2. Zookeeper实践方案:(4)命名服务

    1.基本介绍 命名服务是指通过指定的名字来获取资源或者服务的地址,提供者的信息.利用Zookeeper非常easy创建一个全局的路径,而这个路径就能够作为一个名字.它能够指向集群中的集群.提供的服务的 ...

  3. ZooKeeper实践方案:(7) 分布式锁

    1.基本介绍 分布式锁是控制分布式系统之间同步訪问共享资源的一种方式,须要相互排斥来防止彼此干扰来保证一致性. 利用Zookeeper的强一致性能够完毕锁服务.Zookeeper的官方文档是列举了两种 ...

  4. ZooKeeper实践:(2)集群管理

    前言: 随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机 ...

  5. ZooKeeper实践:(1)集群管理

    前言: 随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机 ...

  6. 部署zookeeper实践

    1.解压zookeeper 2.环境变量设置 hadoop@namenode:~/zookeeper-3.4.6/conf$ sudo vim /etc/profile export JAVA_HOM ...

  7. 分布式锁 ----zookeeper实践 (排它锁)

    排它锁概念: Exclusive Locks,被称为X锁,写锁,独占锁.如果事物T1对数据对象O1加上了排它锁,那么在整个加锁期间,只允许事务T1对O1进行读写操作,其他事务必须等到T1释放锁后才能进 ...

  8. 1、ZooKeeper 基本概念、使用方法、实践场景

    ZooKeeper 基本概念 ZooKeeper 是面向分布式应用的协调服务,其实现了树形结构的数据模型(与文件系统类似),并且提供了简洁的编程原语.ZooKeeper 能够作为基础,用于构建更高层级 ...

  9. Disconf实践指南:安装篇

    Disconf是百度开源出来的一款基于Zookeeper的分布式配置管理软件.目前很多公司都在使用,包括滴滴.百度.网易.顺丰等公司.通过简单的界面操作就可以动态修改配置属性,还是很方便的.使用Dis ...

随机推荐

  1. Linux运维六:用户管理及用户权限设置

    Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.用户的账号一方面可以帮助系统管理员对使用系统的用户进行 ...

  2. mysql 同步数据到 ElasticSearch 的方案

    MySQL Binlog 要通过 MySQL binlog 将 MySQL 的数据同步给 ES, 我们只能使用 row 模式的 binlog.如果使用 statement 或者 mixed forma ...

  3. 织梦自定义表单通过ajax提交的实现方法

    自定义表单通过ajax判断,提交不用跳转页面,提高用户体验.具体方法如下: html表单代码部分,就提交按钮改成botton,,添加onclick事件 表单代码: <form action=&q ...

  4. 不可不看!CSS3中三十一种选择器用法

    原文 The 30 CSS Selectors you Must Memorize 由 Jeffrey Way 发表于 2012 年 6 月,介绍了 30 种最常用的 CSS 选择器用法,多加了一种, ...

  5. [大数据测试]ETL测试或数据仓库测试入门

    转载自: http://blog.csdn.net/zhusongziye/article/details/78633934 概述 在我们学习ETL测试之前,先了解下business intellig ...

  6. Uva 11549 - Calculator Conundrum 找规律加map

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  7. Linux基础-awk使用

    打印uid在30~40范围内的用户名:awk -F: '$3>=30&&$3<040{print $1}' passwd 打印第5-10行的行号和用户名:awk -F: ' ...

  8. BNUOJ 12756 Social Holidaying(二分匹配)

    题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=12756 Social Holidaying Time Limit: 3000ms Memo ...

  9. [转]坐在马桶上看算法:只有五行的Floyd最短路算法

    此算法由Robert W. Floyd(罗伯特·弗洛伊德)于1962年发表在“Communications of the ACM”上.同年Stephen Warshall(史蒂芬·沃舍尔)也独立发表了 ...

  10. web项目打包后在代码中获取资源文件

    在web项目里面,有时代码里面需要引用一些自定义的配置文件,这些配置文件如果放在类路径下,项目经过打包后使用的相对路径也会发生变化,所以以下给出了三种解决方案. 一.properties下配置 在类路 ...