目录
1. NodeCache
这是最简单的一种监听方式,只监听固定节点的内容变化。
public class CuratorBaseTest {
/* url : zookeeper 地址
* namespace : 起始路径
* id0 : 用户名
* id1 : 密码
* */
public static CuratorFramework buildConnect(String url,String namespace, String id0, String id1)
{
//创建权限管理器
ACLProvider aclProvider = new ACLProvider() {
private List<ACL> acl;
@Override public List<ACL> getDefaultAcl() {
if (acl == null) {
ArrayList<ACL> acl = ZooDefs.Ids.CREATOR_ALL_ACL; //初始化
acl.clear();
acl.add(new ACL(Perms.ALL, new Id("auth", id0 + ":" + id1)));//添加
this.acl = acl;
}
return acl;
}
@Override public List<ACL> getAclForPath(String path) {
return acl;
}
};
CuratorFramework curatorFramework =
CuratorFrameworkFactory.builder()
.aclProvider(aclProvider)
.connectString(url)
.authorization("digest", (id0 + ":" + id1).getBytes()) //使用用户名/密码进行连接
.retryPolicy(new ExponentialBackoffRetry(100, 6)) //重试策略
.build();
curatorFramework.start();
try {
curatorFramework.blockUntilConnected(3, TimeUnit.SECONDS); //阻塞判断连接成功,超时认为失败。
if (curatorFramework.getZookeeperClient().isConnected()) {
return curatorFramework.usingNamespace(namespace); //返回连接,起始根目录为namespace。
}
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
// fail situation
curatorFramework.close();
throw new RuntimeException("failed to connect to zookeeper service : " + url);
}
}
public class CuratorNodeCacheTest {
public static void main(String[] args) {
try {
String testPath="nodeCacheTest";
//创建连接
CuratorFramework client= CuratorBaseTest.buildConnect("192.168.10.1:2181,192.168.10.2:2181","test","test","test");
//如果testPath存在,删除路径
Stat stat = client.checkExists().forPath("/"+testPath);
if(stat != null)
{
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/"+testPath);
}
//创建testPath
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/"+testPath,testPath.getBytes());
//创建NodeCache,监控节点内容变化。
final NodeCache nodeCache = new NodeCache(client,"/" + testPath);
nodeCache.start();
//创建listenner
nodeCache.getListenable().addListener(new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
System.out.println("节点内容变化:" + new String(nodeCache.getCurrentData().getData()));
}
});
//第一次修改节点
client.setData().forPath("/" + testPath,"1".getBytes());
//此处如果不睡眠,两次修改时间太近,第一次修改的内容会丢失,监听器会察觉不到第一次修改。
Thread.sleep(1000);
//第二次修改节点
client.setData().forPath("/" + testPath,"2".getBytes());
Thread.sleep(1000);
//删除节点
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/"+testPath);
Thread.sleep(1000);
//重新创建节点
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/"+testPath,testPath.getBytes());
Thread.sleep(1000);
//第三次更改节点
client.setData().forPath("/" + testPath,"3".getBytes());
Thread.sleep(1000);
//关闭
nodeCache.close();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}
输出:
节点内容变化:1
节点内容变化:2
节点内容变化:nodeCacheTest
节点内容变化:3
2. PathChildrenCache
此种方式只监听某个节点的子节点变化,不关心孙子节点的变化。
public class CuratorPathChildrenCacheTest {
public static void main(String[] args) {
try {
String testPath="pathChildrenCacheTest";
//创建连接
CuratorFramework client= CuratorBaseTest.buildConnect("192.168.10.1:2181,192.168.10.2:2181","test","test","test");
//如果testPath存在,删除路径
Stat stat = client.checkExists().forPath("/"+testPath);
if(stat != null)
{
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/"+testPath);
}
//创建testPath
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/"+testPath,testPath.getBytes());
//创建PathChildrenCache
//参数:true代表缓存数据到本地
PathChildrenCache pathChildrenCache = new PathChildrenCache(client,"/" + testPath,true);
//BUILD_INITIAL_CACHE 代表使用同步的方式进行缓存初始化。
pathChildrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
pathChildrenCache.getListenable().addListener((cf, event) -> {
PathChildrenCacheEvent.Type eventType = event.getType();
switch (eventType) {
case CONNECTION_RECONNECTED:
pathChildrenCache.rebuild();
break;
case CONNECTION_SUSPENDED:
break;
case CONNECTION_LOST:
System.out.println("Connection lost");
break;
case CHILD_ADDED:
System.out.println("Child added");
break;
case CHILD_UPDATED:
System.out.println("Child updated");
break;
case CHILD_REMOVED:
System.out.println("Child removed");
break;
default:
}
});
//创建子节点1
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/"+testPath+"/1",testPath.getBytes());
Thread.sleep(1000);
//创建子节点1
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/"+testPath+"/2",testPath.getBytes());
Thread.sleep(1000);
//删除子节点1
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/"+testPath+"/1");
Thread.sleep(1000);
//删除子节点2
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/"+testPath+"/2");
Thread.sleep(1000);
pathChildrenCache.close();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}
输出:
Child added
Child added
Child removed
Child removed
3. TreeCache
此种方式已树形的方式监听某个节点下所有子孙节点的变化,例如子节点的子节点。
public class CuratorTreeCacheTest {
public static void main(String[] args) {
try {
String testPath = "treeCacheTest";
// 创建连接
CuratorFramework client = CuratorBaseTest.buildConnect("192.168.10.1:2181,192.168.10.2:2181", "test", "test",
"test");
// 如果testPath存在,删除路径
Stat stat = client.checkExists().forPath("/" + testPath);
if (stat != null) {
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/" + testPath);
}
// 创建testPath
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/" + testPath,
testPath.getBytes());
final TreeCache cached = new TreeCache(client, "/" + testPath);
cached.getListenable().addListener((cli, event) -> {
TreeCacheEvent.Type eventType = event.getType();
switch (eventType) {
case CONNECTION_RECONNECTED:
break;
case CONNECTION_SUSPENDED:
break;
case CONNECTION_LOST:
System.out.println("Connection lost");
break;
case NODE_ADDED:
System.out.println("Node added:" + event.getData().getPath());
break;
case NODE_UPDATED:
System.out.println("Node updated");
break;
case NODE_REMOVED:
System.out.println("Node removed:" + event.getData().getPath());
break;
default:
}
});
cached.start();
// 创建子节点1
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT)
.forPath("/" + testPath + "/1", testPath.getBytes());
Thread.sleep(1000);
// 创建子节点1/11
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT)
.forPath("/" + testPath + "/1/11", testPath.getBytes());
Thread.sleep(1000);
// 删除子节点1/11
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/" + testPath + "/1/11");
Thread.sleep(1000);
// 删除子节点1
client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/" + testPath + "/1");
Thread.sleep(1000);
cached.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
输出:
Node added:/treeCacheTest
Node added:/treeCacheTest/1
Node added:/treeCacheTest/1/11
Node removed:/treeCacheTest/1/11
Node removed:/treeCacheTest/1