zookeeper在使用上可以通过原生API、zkclient、curator来进行相关操作
maven依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
原生API
建立连接
public class CreateSessionDemo {
private final static String CONNECTSTRING = "192.168.0.119:2181";
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws InterruptedException, IOException {
ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
//如果当前的连接状态是连接成功的,那么通过计数器去控制
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
System.out.println(watchedEvent.getState());
}
countDownLatch.countDown();
}
});
countDownLatch.await();
System.out.println(zooKeeper.getState());
}
}
相关API操作
public class ApiOperatorDemo implements Watcher {
private final static String CONNECTSTRING = "192.168.0.119:2181";
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
/**
* 客户端与服务器建立会话
*
* 因为zookeeper建立会话连接是异步的,所以需要
* 阻塞下当前线程,否则,看不到process函数的回调信息
*
* watchedEvent Type : None
*/
// ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new ApiOperatorDemo());
// countDownLatch.await();
/**
* 创建节点
* watchedEvent Type : NodeCreated
*/
ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new ApiOperatorDemo());
countDownLatch.await();
//设置要监听的节点,true意思是使用默认的watch监听,也就是我们创建
//zookeeper时设置的监听
zooKeeper.exists("/node1", true);
zooKeeper.create("/node1", "123".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
/**
* 删除节点
* watchedEvent Type : NodeDeleted
*/
// ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new ApiOperatorDemo());
// countDownLatch.await();
// zooKeeper.exists("/node1", true);
// zooKeeper.create("/node1", "123".getBytes(),
// ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
// //重新设置watch,zookeeper中watch被调用之后需要重新设置
// zooKeeper.exists("/node1", true);
// //第二个参数 -1 是 version ,在更新操作中如果 版本的参数为 -1 ,则
// //表示更新操作针对任何版本均可。当不为 -1时 如果和节点版本不一致,则更新失败
// zooKeeper.delete("/node1", -1);
/**
* 节点数据修改
* watchedEvent Type : NodeDataChanged
*/
// ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new ApiOperatorDemo());
// countDownLatch.await();
// zooKeeper.exists("/node1", true);
// zooKeeper.create("/node1", "123".getBytes(),
// ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
// zooKeeper.exists("/node1", true);
// //当第三个参数 version 为-1 时 表示无视版本,
// //有一点需要注明的是:节点修改 不管内容有没有变化或者版本号变化 都会出发watch监听
// zooKeeper.setData("/node1", "123".getBytes(), -1);
/**
* 当前节点的子节点列表发生改变
* watchedEvent Type : NodeChildrenChanged
*/
// ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new ApiOperatorDemo());
// countDownLatch.await();
// zooKeeper.exists("/node1", true);
// //这里创建一个持久节点,因为临时节点下是不能创建子节点的
// zooKeeper.create("/node1", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
// CreateMode.PERSISTENT);
// //要关注子节点列表变更不能通过exists方法设置,而是通过getChildren来设置watch
// zooKeeper.getChildren("/node1", true);
// zooKeeper.create("/node1/child-1", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
// CreateMode.PERSISTENT);
/**
* 获取指定节点下的子节点
*/
// ZooKeeper zooKeeper = new ZooKeeper(CONNECTSTRING, 500, new ApiOperatorDemo());
// countDownLatch.await();
// List<String> children = zooKeeper.getChildren("/node1", true);
// System.out.println(children);
}
@Override
public void process(WatchedEvent watchedEvent) {
countDownLatch.countDown();
System.out.println("process--->" + watchedEvent.getType());
}
}
acl操作
public class AuthControlDemo implements Watcher {
private final static String CONNECTSTRING = "192.168.0.119:2181";
private static CountDownLatch countDownZookeeper1 = new CountDownLatch(1);
private static CountDownLatch countDownZookeeper2 = new CountDownLatch(1);
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zooKeeper1 = new ZooKeeper(CONNECTSTRING, 500, new AuthControlDemo());
countDownZookeeper1.await();
/**
* ACL
* 第一个参数是 Zookeeper的权限类型
* 权限类型有:
* CREATE: 能创建子节点
* READ:能获取节点数据和列出其子节点
* WRITE: 能设置节点数据
* DELETE: 能删除子节点
* ADMIN: 能设置权限
* 第二个参数是认证方式
* 认证方式有四种
* world:默认方式,相当于全世界都能访问
* auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
* digest:即用户名:密码这种方式认证,这也是业务系统中最常用的
* ip:使用Ip地址认证
*
*/
ACL aclDigest = new ACL(ZooDefs.Perms.ALL, new Id("digest", "root:root"));
// ACL aclIp = new ACL(ZooDefs.Perms.CREATE, new Id("ip", "192.168.0.119"));
List<ACL> acls = new ArrayList<>();
acls.add(aclDigest);
// acls.add(aclIp);
// zooKeeper1.create("/node1", "123".getBytes(), acls, CreateMode.PERSISTENT);
// zooKeeper1.addAuthInfo("digest","root:root".getBytes());
ZooKeeper zooKeeper2 = new ZooKeeper(CONNECTSTRING, 500, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
countDownZookeeper2.countDown();
System.out.println("zooKeeper2.watchedEvent--->"+watchedEvent);
}
});
countDownZookeeper2.await();
// zooKeeper2.addAuthInfo("digest","root:root".getBytes());
zooKeeper2.delete("/node1", -1);
// byte[] data = zooKeeper2.getData("/node1", null, new Stat());
// System.out.println(new String(data));
}
@Override
public void process(WatchedEvent watchedEvent) {
countDownZookeeper1.countDown();
}
}