JAVA Zookeeper分布式配置注册发现代码
JAVA Zookeeper分布式配置注册发现代码
zookeeper利用Watch 和 AsyncCallback 特性,如果某一节点状态发生变化会及时被服务所感知…
膜拜大佬和加上自己感悟写下如下code…
如果有不对异议的地方欢迎留言一起探讨….[抱拳]
测试类代码
import org.apache.zookeeper.ZooKeeper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class TestConfig {
private ZooKeeper zk;
@Before
public void getZk() throws Exception {
zk = ZkUtils.getZk();
}
@After
public void close() throws Exception {
ZkUtils.closeZK();
}
@Test
public void getConf() throws Exception {
WatchCallBack watchCallBack = new WatchCallBack();
watchCallBack.setZk(zk);
MyConf myConf = new MyConf();
watchCallBack.setMyConf(myConf);
watchCallBack.setCd(1);
watchCallBack.aWait();
while (true) {
if (myConf.getConf().equals("")) {
System.out.println("节点被删除................");
watchCallBack.aWait();
} else {
Thread.sleep(1000);
System.out.println(myConf.getConf());
}
}
}
Watch、AsyncCallback . . .
/*
* 0 创建节点 ,节点被修改都会执行 ->
* zk.getData("/AppConf", this, this, "ABC") -> 去触对应的回调;
* 1 调用await时
* zk.exists("/AppConf", this, this, "ABC"); 会触发 statCallBack回调
* 2 public void processResult(int i, String s, Object o, Stat stat) -->被回调时 statCallBack回调
* 如果stat不为null代表节点已经被创建
* zk.getData("/AppConf", this, this, "ABC");会触发 DataCallback (用于获取节点的数据和状态回调)
* 3 public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) 被回调时
* 如果 bytes不为null 给myConf(自己创建的用于接收数据)设置值 并cd.countDown()
* 4 cd.countDown()后 wait等待代码接触wait-> 继续往下执行
* 5 当节点有事件发生时,会触发回调watcher---> public void process(WatchedEvent watchedEvent)
* watcher会有不同的事件类型 create delete change childChange
* 根据不同的事件类型做不同的业务
* */
// Watcher关注的是节点的状态变化,
// AsyncCallback关注的是API调用返回结果,
// 一个是监听节点将来的变化,一个是获取节点当前的状态或数据,所以两者并不冲突,也可以共存。
//异步API:跟同步API相反,客户端调用完后,不需要等待zk返回结果,客户端继续执行后面的代码,
// 但是需要设置一个AsyncCallback回调,当zk服务器返回结果后,
// 会回调客户端注册的这个AsyncCallback中的processResult()方法。来处理返回结果。
public class WatchCallBack implements Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback {
private ZooKeeper zk;
private MyConf MyConf;
private CountDownLatch cd;
public MyConf getMyConf() {
return MyConf;
}
public void setMyConf(MyConf MyConf) {
this.MyConf = MyConf;
}
public ZooKeeper getZk() {
return zk;
}
public void setZk(ZooKeeper zk) {
this.zk = zk;
}
public void setCd(int init) {
System.out.println("设置countDown------->" + "set init....");
this.cd = new CountDownLatch(init);
}
/**
* DataCallback 用于获取节点的数据和状态
*
* @param i
* @param s
* @param o
* @param bytes
* @param stat
*/
@Override
public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
System.out.println("2222222222222222222222222");
if (bytes != null) {
MyConf.setConf(new String(bytes));
cd.countDown();
}
}
/**
* StatCallback 用于获取节点的状态
*
* @param i
* @param s
* @param o
* @param stat
*/
@Override
public void processResult(int i, String s, Object o, Stat stat) {
if (stat != null) {
//stat不为空代表节点存在
System.out.println("11111111111111111111");
//getData会回调回调上面方法-->DataCallback 用于获取节点的数据和状态
zk.getData("/AppConf", this, this, "ABC");
}
}
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("回调watch---------------------->" + watchedEvent.toString());
switch (watchedEvent.getType()) {
case None:
break;
case NodeCreated:
System.out.println("<----------节点被创建---------->");
zk.getData("/AppConf", this, this, "ABC");
break;
case NodeDeleted:
System.out.println("<----------节点被删除---------->");
MyConf.setConf("");
cd = new CountDownLatch(1);
break;
case NodeDataChanged:
System.out.println("<----------节点被修改---------->");
zk.getData("/AppConf", this, this, "ABC");
break;
case NodeChildrenChanged:
break;
}
}
public void aWait() throws Exception {
//节点是否存在会回调-->StatCallback 用于获取节点的状态
zk.exists("/AppConf", this, this, "ABC");
cd.await();
}
}
ZkUtils …
import org.apache.zookeeper.ZooKeeper;
import java.util.concurrent.CountDownLatch;
public class ZkUtils {
private static ZooKeeper zk;
private static DefaultWatch watch = new DefaultWatch();
private static CountDownLatch cd = new CountDownLatch(1);
public static ZooKeeper getZk () throws Exception {
zk = new ZooKeeper("127.0.0.1:2181/weilai",1000,watch);
watch.setCd(cd);
cd.await();
return zk;
}
public static void closeZK () throws Exception {
if (zk!=null){
zk.close();
}
}
}
DefaultWatch … (不太重要)
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import java.util.concurrent.CountDownLatch;
public class DefaultWatch implements Watcher {
private CountDownLatch cd;
public CountDownLatch getCd() {
return cd;
}
public void setCd(CountDownLatch cd) {
this.cd = cd;
}
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("defaultWatcher打印事件--------->" + watchedEvent.toString());
switch (watchedEvent.getState()) {
case Unknown:
break;
case Disconnected:
System.out.println("defaultWatcher-------------连接断开---------Disconnected------->");
cd = new CountDownLatch(1);
break;
case NoSyncConnected:
break;
case SyncConnected:
System.out.println("defaultWatcher-------------连接成功---------SyncConnected------->");
cd.countDown();
break;
case AuthFailed:
break;
case ConnectedReadOnly:
break;
case SaslAuthenticated:
break;
case Expired:
break;
}
}
}
MyConf 用于接收数据
/**
* 用来接收业务数据
*/
public class MyConf {
private String conf;
public String getConf() {
return conf;
}
public void setConf(String conf) {
this.conf = conf;
}
}
部分测试结果
defaultWatcher打印事件--------->WatchedEvent state:SyncConnected type:None path:null
defaultWatcher-------------连接成功---------SyncConnected------->
设置countDown------->set init....
11111111111111111111
2222222222222222222222222
nihadsd
nihadsd
nihadsd
nihadsd
回调watch---------------------->WatchedEvent state:SyncConnected type:NodeDataChanged path:/AppConf
<----------节点被修改---------->
2222222222222222222222222
nihaoweilai
nihaoweilai
nihaoweilai
nihaoweilai
回调watch---------------------->WatchedEvent state:SyncConnected type:NodeDeleted path:/AppConf
<----------节点被删除---------->
节点被删除................
回调watch---------------------->WatchedEvent state:SyncConnected type:NodeCreated path:/AppConf
<----------节点被创建---------->
2222222222222222222222222
weilai
weilai
weilai
weilai
如有不对异议欢迎指出大家一起探讨…[抱拳][抱拳][抱拳]