文档章节

分布式服务框架 Zookeeper之配置管理

醉饮黄龙
 醉饮黄龙
发布于 2015/01/23 15:12
字数 942
阅读 156
收藏 0

实现说明:

客户端实现zookeeper的watcher事件,监听节点的更新事件,zookeeper管理的节点配置有更新时,客户端会接收到更新事件,并作出相应的处理,本文代码只是一个简单的示例


服务端代码示例

/**
 * 包名:com.lencee.demo.zookeeper.config
 * 文件名:ConfigManager.java
 * 版本信息:
 * 日期:2015年1月23日-下午1:28:55
 * 
 */
package com.lencee.demo.zookeeper.config;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
/**
 * 
 * <p>配置管理类<p>
 * <p>维护分布式配置</p>
 * @version 2015年1月23日 下午1:28:55
 * 
 */
public class ConfigManager {
 
 private static ConfigManager configManager = null;
 
 //Zookeeper集群服务地址与端口
 private static String zkUrl = "192.168.0.101:11001";
 //配置结点根路径
 private final static String ROOT = "/myConf";
 //结点鉴权方式
 private final static String AUTH_TYPE = "digest";
 //结点鉴权密码
 private final static String AUTH_PWD = "password";
 
 private ZooKeeper zk = null;
 
 private ConfigManager(){}
 
 public synchronized static ConfigManager getInstance() throws Exception{
  if (configManager == null) {
   configManager = new ConfigManager();
   ZooKeeper zk = new ZooKeeper(zkUrl, 3000, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
     System.out.println("事件类型:" + event.getType());
    }
   });
   while (zk.getState() != ZooKeeper.States.CONNECTED) {
    Thread.sleep(3000);
   }
   
   //给这个链接添加认证信息
   zk.addAuthInfo(AUTH_TYPE, AUTH_PWD.getBytes());
   
   configManager.setZk(zk);
   
   String rootValue = "测试环境配置";
   if(zk.exists(ROOT, true)==null){
    //结点不存在
    zk.create(ROOT , rootValue.getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
   }
  }
  return configManager;
 }
 
 public void addNode(String path,byte[] data,CreateMode createMode) throws Exception{
  if(!path.startsWith("/")){
   throw new Exception("传入的路径没有以'/'开始");
  }
  if(this.zk.exists(ROOT + path, true)==null){
   //结点不存在
   this.zk.create(ROOT + path, data, Ids.CREATOR_ALL_ACL, createMode);
  }
 }
 public void setDate(String path,byte[] data) throws Exception{
  if(this.zk.exists(ROOT + path, true)==null){
   addNode(path, data, CreateMode.PERSISTENT);
  }else{
   zk.setData(ROOT + path, data, -1);
  }
  
 }
 /**
  * zk
  *
  * @return  the zk
  * @since   1.0.0
  */
 public ZooKeeper getZk() {
  return zk;
 }
 /**
  * @param zk the zk to set
  */
 public void setZk(ZooKeeper zk) {
  this.zk = zk;
 }
 
 public static void main(String[] args) throws Exception {
  ConfigManager cfm = ConfigManager.getInstance();
  
  //添加数据库配置节点
  String path = "/mysql";
  String value = "测试环境Mysql配置";
  cfm.setDate(path, value.getBytes());
  
  //添加项目配置节点
  String octopusPath = "/mysql/octopus";
  String octopusValue = "资源系统";
  cfm.setDate(octopusPath, octopusValue.getBytes());
  
  //添加连接URL的配置
  String urlPath = "/mysql/octopus/url";
  String urlValue = "jdbc:mysql://test.xxx.com:3306/octopus?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
  cfm.setDate(urlPath, urlValue.getBytes());
  //添加连接数据库的用户名配置
  String userPath = "/mysql/octopus/username";
  String userValue = "octopus";
  cfm.setDate(userPath, userValue.getBytes());
  //添加连接数据库的密码配置
  String pwdPath = "/mysql/octopus/pwd";
  String pwdValue = "octopus111";
  cfm.setDate(pwdPath, pwdValue.getBytes());
 }
}

客户端代码

/**
 * 包名:com.lencee.demo.zookeeper.config
 * 文件名:ConfigClient.java
 * 版本信息:
 * 日期:2015年1月23日-下午2:15:49
 * 
 */
package com.lencee.demo.zookeeper.config;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooKeeper;
/**
 * 
 * <p>配置应用端<p>
 * <p>读取分布式配置</p>
 * @version 2015年1月23日 下午2:15:49
 * 
 */
public class ConfigClient implements Watcher{
 
 // Zookeeper集群服务地址与端口
 private static String zkUrl = "192.168.0.101:11001";
 // 配置结点根路径
 private final static String ROOT = "/myConf";
 // 结点鉴权方式
 private final static String AUTH_TYPE = "digest";
 // 结点鉴权密码
 private final static String AUTH_PWD = "password";
 private ZooKeeper zk = null;
 
 private String url;
 private String username;
 private String pwd;
 
 public ConfigClient() {
  try {
   ZooKeeper zk = new ZooKeeper(zkUrl, 3000,this);
   while (zk.getState() != ZooKeeper.States.CONNECTED) {
    Thread.sleep(3000);
    System.out.println();
   }
   
   //给这个链接添加认证信息
   zk.addAuthInfo(AUTH_TYPE, AUTH_PWD.getBytes());
   this.zk = zk;
   //读取服务端的配置
   reflushValue();
  } catch (Exception e) {
   e.printStackTrace();
  } 
 }
 /**
  * 
  * reflushValue:<p>将配置服务设置的配置更新到对象中</p> 
  * @since  1.0.0
  */
 public void reflushValue() {
  try {
   this.url = new String(this.zk.getData(ROOT + "/mysql/octopus/url", true, null));
   this.username = new String(this.zk.getData(ROOT + "/mysql/octopus/username", true, null));
   this.pwd = new String(this.zk.getData(ROOT + "/mysql/octopus/pwd", true, null));
  } catch (Exception e) {
   e.printStackTrace();
  } 
 }
 
 public void printValues(){
  System.out.println("----------------当前配置---------------");
  System.out.println("mysql.url:"+this.url);
  System.out.println("mysql.username:"+this.username);
  System.out.println("mysql.pwd:"+this.pwd);
 }
 
 @Override
 public void process(WatchedEvent event) {
  EventType eventType = event.getType();
  if(Watcher.Event.EventType.None==eventType){
   System.out.println("事件:连接服务成功");
  }else if(Watcher.Event.EventType.NodeCreated==eventType){
   System.out.println("事件:节点创建成功");
  }else if(Watcher.Event.EventType.NodeChildrenChanged==eventType){
   System.out.println("事件:子节点更新成功");
   reflushValue();
   printValues();
  }else if(Watcher.Event.EventType.NodeDataChanged==eventType){
   System.out.println("事件:节点更新成功");
   reflushValue();
   printValues();
  }else if(Watcher.Event.EventType.NodeDeleted==eventType){
   System.out.println("事件:节点删除成功");
  }
  
 }
 /**
  * url
  *
  * @return  the url
  * @since   1.0.0
  */
 public String getUrl() {
  return url;
 }
 /**
  * username
  *
  * @return  the username
  * @since   1.0.0
  */
 public String getUsername() {
  return username;
 }
 /**
  * pwd
  *
  * @return  the pwd
  * @since   1.0.0
  */
 public String getPwd() {
  return pwd;
 }
 public static void main(String[] args) throws Exception {
  ConfigClient cc = new ConfigClient();
  System.out.println("客户端开始运行"+cc);
  while(true){
   Thread.sleep(3000);
  }
 }
}

© 著作权归作者所有

醉饮黄龙
粉丝 1
博文 17
码字总数 16194
作品 0
江北
私信 提问
加载中

评论(0)

分布式网站架构后续:zookeeper技术浅析

 Zookeeper是hadoop的一个子项目,虽然源自hadoop,但是我发现zookeeper脱离hadoop的范畴开发分布式框架的运用越来越多。今天我想谈谈zookeeper,本文不谈如何使用zookeeper,而是zookeeper...

蓝狐乐队
2014/04/21
309
0
基于 ZooKeeper 实现爬虫集群的监控

ZooKeeper ZooKeeper 是一个开源的分布式协调服务,ZooKeeper框架最初是在“Yahoo!"上构建的,用于以简单而稳健的方式访问他们的应用程序。 后来,Apache ZooKeeper成为Hadoop,HBase和其他分...

fengzhizi715
2019/05/26
0
0
ZooKeeper可以用来做什么(转)

在ZooKeeper的官网上有这么一句话:ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing grou......

easonjim
2017/09/05
0
0
【Zookeeper】基础学习概览【汇总】

一、概述 1.1 简介 1.2 Zookeeper集群机制 1.3 Zookeeper特性 二、Zookeeper应用场景 三、Zookeeper数据结构 四、Zookeeper安装 五、Java操作Zookeeper 六、Zookeeper实现负载均衡 七、Zooke...

osc_xgq4n4ik
04/16
8
0
框架-thrift-zookeeper-kafka

Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RE...

osc_w6ajhfm8
2018/07/28
4
0

没有更多内容

加载失败,请刷新页面

加载更多

web测试与app测试的区别

web测试与app测试的区别 首先从系统架构来看的话: web项目,一般都是b/s架构,基于浏览器的,而app则是c/s的,必须要有客户端。那么在系统测试测试的时候就会产生区别了。 web测试只要更新了...

osc_qo89by3k
5分钟前
5
0
【mysql 读写分离】10分钟了解读写分离的作用

1、什么是读写分离 读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集...

战略板儿砖
6分钟前
9
0
Sphinx和rst在科研笔记和学术博客中的高效用法

什么是RST? reStructuredText 是扩展名为 .rst 的纯文本文件,含义为"重新构建的文本",也被简称为:RST 或 reST; 是 Python 编程语言的 Docutils 项目的一部分,Python Doc-SIG (Documen...

osc_6b3uvobr
6分钟前
9
0
MySQL 的 crash-safe 原理解析

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/5i9wmJs4_Er7RaYfNnETyA 作者:xieweipeng MySQL作为当下最流行的开源关系型数据库,有一个很关键和基本的能力,就...

vivo互联网技术
7分钟前
10
0
Org Mode - 年轻人的第一堂时间管理课程

忙成狗,闲成猪。 上半年我的状态就是如此,为了做出改变我找了很多的任务管理工具,比如奇妙清单、滴答清单(现在我还在用)等等,但是依然没有满足我的需求。作为一名精力旺盛的开发仔,我...

osc_smzoc82r
7分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部