03年,作者大二买了第一台计算机。记得那时候2种主题的书特别多,注册表和Bios。现在想想《教你21天玩转Bios》这样的书名都像个笑话儿。 这么说是因为BOIS和注册表对普通用户,基本用不上。但是注册表其实是Windows系统中非常重要的组件,提供了配置存储、事件监听响应等机制,Windows中很多服务开发都需要依赖注册表。
ZooKeeper 典型的应用场景,限于篇幅就不详细展开,百度或https://www.jianshu.com/p/1e052bddba80
当你了解了这些应用场景,会不会明白作者将zookeeper和注册表对标的想法?
写作日期为2018.6.17,zookeeper版本为3.4.9。
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
<type>pom</type>
</dependency>
new Zookeeper是一个异步函数,调用之后马上返回。注册一个Watch回调函数,通常在这个函数中确认连接成功。用DownLatch.await等待确认连接成功。
CountDownLatch countDownLatch = new CountDownLatch(1);
ZooKeeper zk = new ZooKeeper("172.18.0.71:2181", 20000,
new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("process " + watchedEvent);
if (watchedEvent.getState() ==
Event.KeeperState.SyncConnected) {
countDownLatch.countDown();
}
}
});
try {
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
指明节点路径和节点上保存的数据。通常可以用JSON保存更多信息。
/*
public String create(final String path, byte data[], List<ACL> acl,
CreateMode createMode)
*/
try {
zk.create("/wsn","try creat".getBytes()
,ZooDefs.Ids.OPEN_ACL_UNSAFE
,CreateMode.PERSISTENT);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
创建临时节点,该节点通常被认为是进程的替身,如果节点被删除,那么原进程已经退出。CreateMode指明节点类型。
try {
zk.create("/wsn_t","EPHEMERAL".getBytes()
,ZooDefs.Ids.OPEN_ACL_UNSAFE
,CreateMode.EPHEMERAL);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
List<String> children = zk.getChildren("/wsn",new MyWatcher());
Iterator<String> iter = children.iterator();
while (iter.hasNext())
{
System.out.println("path :"+iter.next());
}
ret = zk.getData("/wsn", null,stat);
System.out.println("info:"+new String(ret));
System.out.println(stat);
info:wsn test path 748,748,1534087028795,1534087028795,0,15,0,0,13,5,770
public class Stat implements Record {
private long czxid;
private long mzxid;
private long ctime;
private long mtime;
private int version;
private int cversion;
private int aversion;
private long ephemeralOwner;
private int dataLength;
private int numChildren;
private long pzxid;
}
状态属性 说明 cZxid 数据节点创建时的事务ID ctime 数据节点创建时的时间 mZxid 数据节点最后一次更新时的事务ID mtime 数据节点最后一次更新时的时间 pZxid 数据节点的子节点列表最后一次被修改(是子节点列表变更,而不是子节点内容变更)时的事务ID cversion 子节点的版本号 dataVersion 数据节点的版本号 aclVersion 数据节点的ACL版本号 ephemeralOwner 如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为0 dataLength 数据内容的长度 numChildren 数据节点当前的子节点个数
Sets data on the node, or deletes the node.设置数据和删除节点
deletes the node of the given path or creates/delete a child under the node删除节点(通getData),子节点创建和删除;不响应孙子节点,和更改状态。 注:监听事件只响应一次。响应后需再次注册监听。
private static class MyWatcher implements Watcher
{
@Override
public void process(WatchedEvent event) {
System.out.println("getChildren trigger");
System.out.println("event tpye:"+event.getType());
System.out.println("event state:"+event.getState());
System.out.println("event path"+event.getPath());
try {
zk.getChildren("/wsn",new MyWatcher()); //再注册
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
为/wsn目录设置一个监听器。
zk.getChildren("/wsn",new MyWatcher());
实验,通过zkCli为/wsn添加一个临时节点。
[zk: localhost:2181(CONNECTED) 1] create -e /wsn/exam 'test' Created /wsn/exam
getChildren trigger event tpye:NodeChildrenChanged event state:SyncConnected event path/wsn
实验演示,创建序列节点,生成00和01两个节点。
zk.create("/wsn/seq/no"
,"wsn_seq".getBytes()
,ZooDefs.Ids.OPEN_ACL_UNSAFE
,CreateMode.EPHEMERAL_SEQUENTIAL);
zk.create("/wsn/seq/no"
,"wsn_seq_another".getBytes()
,ZooDefs.Ids.OPEN_ACL_UNSAFE
,CreateMode.PERSISTENT_SEQUENTIAL);
[zk: localhost:2181(CONNECTED) 2] ls /wsn/sequence [no0000000001, no0000000000]
通过zookeeper API练习实验,可以加深理解zookeeper的原理。在zookeeperApi的基础上,可以扩展出更多的业务场景,满足分布式场景高可靠、命名、选举等需求。