一端不停的更新配置,另一端监听这个配置的变化。

    需要注意的是:监听端不一定读取到所有的变化。在zk服务器发送通知到客户端,客户端读取数据注册监听之间可能发生了多次数据变化,这些数据变化是得不到通知的。但可以保证的是每次通知得到的数据都是比之前的数据要新的。
 
ZKUtils.java
package config;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
public class ZKUtils {
/**
* 构建zookeeper客户端对象
* @param hosts
* @return
* @throws Exception
*/
public static ZooKeeper open(String hosts) throws Exception {
final CountDownLatch singal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper(hosts, 2000, new Watcher() {
@Override
public void process(WatchedEvent event) {
singal.countDown();
}
}); singal.await(); return zk;
}
}

  

ConfigUpdater.java

package config;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
/**
* 不停的更新/test节点上的数据, 模拟配置更新
*
*/
public class ConfigUpdater {
public static final String HOSTS = "hadoop1:2181";
public static final String PATH = "/test"; public static void main(String[] args) throws Exception {
ZooKeeper zk = ZKUtils.open(HOSTS); while(true) {
String data = UUID.randomUUID().toString(); Stat stat = zk.exists(PATH, false);
if(stat == null) {
zk.create(PATH, data.getBytes("UTF-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} else {
zk.setData(PATH, data.getBytes("UTF-8"), -1);
} TimeUnit.SECONDS.sleep(5);
}
}
}

  

ConfigUpdateWatcher .java

package config;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooKeeper;
/**
* 注册监听/test节点上的数据变化
*
*/
public class ConfigUpdateWatcher implements Watcher {
private ZooKeeper zk = null; public ConfigUpdateWatcher() {
try {
zk = ZKUtils.open(ConfigUpdater.HOSTS);
} catch (Exception e) {
e.printStackTrace();
}
} @Override
public void process(WatchedEvent event) {
System.out.println(event); if(event.getType().equals(EventType.NodeDataChanged)) {
try {
//读取事件后, 再次注册数据监听事件
byte[] data = zk.getData(ConfigUpdater.PATH, this, null);
System.out.printf("接收到了事件%s, 新的数据是:%s", EventType.NodeDataChanged, new String(data, "UTF-8"));
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
} private void run() {
try {
//注册数据变化监听
zk.getData(ConfigUpdater.PATH, this, null);
} catch (Exception e) {
e.printStackTrace();
} try {
TimeUnit.SECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
new ConfigUpdateWatcher().run();
}
}

  

完善

在操作zookeeper的时候,如果是幂等操作(多次操作不影响结果),在失败时可以多次重试以增加可靠性,比如ConfigUpdater的写操作可以进行多次重试,修改后的代码如下:
package config;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
/**
* 不停的更新/test节点上的数据, 模拟配置更新
*
*/
public class ConfigUpdater {
public static final String HOSTS = "hadoop1:2181";
public static final String PATH = "/test";
public static final int RETRIES = 3; //重试次数
public static final int RETRY_PERIOD = 500; //重试间隔 public static void main(String[] args) throws Exception {
ZooKeeper zk = ZKUtils.open(HOSTS); //不停的模拟数据更新操作
while(true) { String data = UUID.randomUUID().toString(); /*
* 多次重试,增加可靠性
*/
int retied = 0;
while(true) {
try {
Stat stat = zk.exists(PATH, false);
if(stat == null) {
zk.create(PATH, data.getBytes("UTF-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} else {
zk.setData(PATH, data.getBytes("UTF-8"), -1);
} //执行成功则跳出循环,否则继续(重试)
break;
} catch (KeeperException e) {
retied++; //如果会话过期了则重新创建一个ZooKeeper客户端对象
if(e.code().equals(KeeperException.Code.SESSIONEXPIRED)) {
zk = ZKUtils.open(HOSTS);
} else {
//其他KeeperException Code的处理 //KeeperException.Code.CONNECTIONLOSS异常可以不用处理:ZooKeeper客户端对象会自动进行重新连接
} //可以重试3次,每次间隔500毫秒
if(retied == RETRIES) {
throw e;
} else {
TimeUnit.MICROSECONDS.sleep(RETRY_PERIOD);
}
}
} //模拟其他操作占用的时间
TimeUnit.SECONDS.sleep(5);
}
}
}

  

zookeeper应用 - 配置服务的更多相关文章

  1. ZooKeeper系列1:ZooKeeper的配置

    问题导读:1.zookeeper有哪些配置文件?2.zookeeper最低配置需要哪些配置项?3.zookeeper高级配置需要配置哪些项? ZooKeeper 的功能特性通过 ZooKeeper 配 ...

  2. ZooKeeper学习第二期--ZooKeeper安装配置

    一.Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式. ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境:■ 伪集群模式:就是在一台物 ...

  3. [转载] zookeeper 分布式锁服务

    转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...

  4. dubbo+zookeeper+springboot构建服务

    本次和大家分享的是dubbo框架应用的初略配置和zookeeper注册中心的使用:说到注册中心现在我使用过的只有两种:zookeeper和Eureka,zk我结合dubbo来使用,而Eureka结合s ...

  5. Zookeeper系列一:Zookeeper介绍、Zookeeper安装配置、ZK Shell的使用

    https://www.cnblogs.com/leeSmall/p/9563547.html 一.Zookeeper介绍 1. 介绍Zookeeper之前先来介绍一下分布式 1.1 分布式主要是下面 ...

  6. ZooKeeper: 简介, 配置及运维指南

    1. 概览 ZooKeeper是一个供其它分布式应用程序使用的软件, 它为其它分布式应用程序提供所谓的协调服务. 所谓的协调服务, 是指ZooKeeper的如下能力 naming 命名 configu ...

  7. 【Zookeeper系列】ZooKeeper安装配置(转)

    原文链接:https://www.cnblogs.com/sunddenly/p/4018459.html 一.Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪 ...

  8. Zookeeper系列四:Zookeeper实现分布式锁、Zookeeper实现配置中心

    一.Zookeeper实现分布式锁 分布式锁主要用于在分布式环境中保证数据的一致性. 包括跨进程.跨机器.跨网络导致共享资源不一致的问题. 1. 分布式锁的实现思路 说明: 这种实现会有一个缺点,即当 ...

  9. 【转载】ZooKeeper学习第二期--ZooKeeper安装配置

    原文地址(https://www.cnblogs.com/sunddenly/p/4018459.html) 一.Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及 ...

随机推荐

  1. 通过Groovy来消除代码噪声

    通过Groovy来消除代码噪声 Java是在JVM上运行的最广泛使用的编程语言.不过,还有很多其他基于JVM的语言,比如Groovy,Scala,JRuby,Jython,Kotlin等等.其中,Gr ...

  2. 《Android应用性能优化》2——内存、CPU、性能测评

    4.高效使用内存 4.1 说说内存 Android设备的性能主要取决于以下三因素: CPU如何操纵特定的数据类型: 数据和指令需占用多少存储空间: 数据在内存中的布局 4.2 数据类型 int和lon ...

  3. Chapter 3 Phenomenon——3

    It took every ounce of my concentration to make it down the icy brick driveway alive. 我用所有我的注意力去确定车道 ...

  4. Linux笔记:vi常用命令

    vi编辑器是所有Unix及Linux系统下标准的编辑器,在很多时候我们都需要使用vi修改服务端配置,vi其实非常强大,只要命令使用熟练的情况下,编辑速度并不亚于现在的图形化编辑器,这里简单地介绍一下它 ...

  5. android学习-仿Wifi模块实现

    最近研究android内核-系统关键服务的启动解析,然而我也不知道研究wifi的作用,就当兴趣去做吧(其实是作业-_-) 系统原生WiFI功能大概有:启动WiFI服务,扫描WiFi信息(这个好像已经被 ...

  6. java主线程结束和子线程结束之间的关系

    (一)Main线程是个非守护线程,不能设置成守护线程. 这是因为,main线程是由java虚拟机在启动的时候创建的.main方法开始执行的时候,主线程已经创建好并在运行了.对于运行中的线程,调用Thr ...

  7. Nginx 为 Golang 配置 web 服务

    server { charset utf-; client_max_body_size 128M; #listen ; ## 监听 ipv4 上的 端口 #listen [::]: default_s ...

  8. 使用Visual Studio Code搭建PHP调试环境

    1.需要安装的软件 Visual Studio Code. WAMP(包括Apache.MySQL.PHP.以及最关键的XDebug) 2.下载软件 Visual Studio Code,光看名字就知 ...

  9. JBoss Web和Tomcat的区别

    在Web2.0的时代,基于Tomcat内核的JBoss在J2EE应用服务器领域已成为发展最为迅速的应用服务器.这一青出于蓝而胜于蓝的产品与Tomcat的区别又在哪里? 基于Tomcat内核,青胜于蓝. ...

  10. 前端富文本编辑器 vue-html5-editor

    1..项目创建与初始化 在安装好脚手架的依赖后,要执行 npm install vue-html5-editor -S 来安装这个富文本插件,由于这个富文本插件的图标是依赖font-awesome.c ...