
本文共 3687 字,大约阅读时间需要 12 分钟。
1、环境准备
需要在项目中导入zookeeper所需的jar包,这里使用maven管理。
org.apache.zookeeper zookeeper 3.4.13
2、连接服务端
创建好项目以后就可以使用java连接zookeeper的服务端了,zookeeper封装了Zookeeper类进行操作。
ZooKeeper zooKeeper = new ZooKeeper("127.0.0.1:2181", 5000, watcher);
ZooKeeper类的构造函数一共有三个参数:第一个参数是服务器的地址,第二个参数是session超时时间,第三个参数是org.apache.zookeeper.Watcher类型的对象。zookeeper api与服务器建立连接是异步的,上面的调用会马上从ZooKeeper构造函数返回。当与服务器建立好连接之后会调用Watcher中的process方法进行处理,我们需要重写process方法,可以在这里实现一些自己的业务功能,process方法会接受一个WatchedEvent类型的参数,用于表明发生了什么事件。
@Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { System.out.println("Watch received event"); } }
WatchedEvent包含两方面重要信息:
- 与zk服务器连接的状态信息 可以调用
watchedEvent.getState()
方法获取与zk服务器连接的状态信息,状态信息取值主要包括SyncConnected、Disconnected、ConnectedReadOnly和AuthFailed等等。 - 发生的具体事件类型信息
watchedEvent.getState()
方法只是获取与zk服务器连接的状态信息,但在同一个连接状态下,还会发生很多事件的类型。例如在zk中,我们可以watch一个节点的数据内容,当这个节点的数据被改变时,我们可以获取到这个事件。类似的还有子节点列表变化事件等等。 这就需要我们在SyncConnected同一种连接状态下区分多个事件类型。可以通过watchedEvent.getType()
方法获取具体的事件类型。事件类型的取值包括None、NodeCreated、NodeDeleted、NodeDataChanged和NodeChildrenChanged。
3、Zookeeper的基本操作
Zookeeper中所有的操作都支持同步和异步两种方式。异步方式在同步方式的基础之上,增加了Callback和context两个参数,使用Callback类作为回调;使用context作为一次事件的标识,常用的API如表1,
表 1 org.apache.zookeeper. ZooKeeper 方法列表
方法名 | 方法功能描述 |
---|---|
( path, byte[] data, <> acl, createMode) | 创建一个给定的目录节点 path, 并给它设置数据, 标识有四种形式的目录节点,分别是 PERSISTENT:持久化目录节点,这个目录节点存储的数据不会丢失;PERSISTENT_SEQUENTIAL:顺序自动编号的目录节点,这种目录节点会根据当前已近存在的节点数自动加 1,然后返回给客户端已经成功创建的目录节点名;EPHEMERAL:临时目录节点,一旦创建这个节点的客户端与服务器端口也就是 session 超时,这种节点会被自动删除;EPHEMERAL_SEQUENTIAL:临时自动编号节点 |
( path, boolean watch) | 判断某个 path 是否存在,并设置是否监控这个目录节点,这里的 watcher 是在创建 ZooKeeper 实例时指定的 watcher,方法还有一个重载方法,可以指定特定的 watcher |
( path, watcher) | 重载方法,这里给某个目录节点设置特定的 watcher,Watcher 在 ZooKeeper 是一个核心功能,Watcher 可以监控目录节点的数据变化以及子目录的变化,一旦这些状态发生变化,服务器就会通知所有设置在这个目录节点上的 Watcher,从而每个客户端都很快知道它所关注的目录节点的状态发生变化,而做出相应的反应 |
void ( path, int version) | 删除 path 对应的目录节点,version 为 -1 可以匹配任何版本,也就删除了这个目录节点所有数据 |
<> ( path, boolean watch) | 获取指定 path 下的所有子目录节点,同样 方法也有一个重载方法可以设置特定的 watcher 监控子节点的状态 |
( path, byte[] data, int version) | 给 path 设置数据,可以指定这个数据的版本号,如果 version 为 -1 怎可以匹配任何版本 |
byte[] ( path, boolean watch, stat) | 获取这个 path 对应的目录节点存储的数据,数据的版本等信息可以通过 stat 来指定,同时还可以设置是否监控这个目录节点数据的状态 |
void ( scheme, byte[] auth) | 客户端将自己的授权信息提交给服务器,服务器将根据这个授权信息验证客户端的访问权限。 |
( path, <> acl, int version) | 给某个目录节点重新设置访问权限,需要注意的是 Zookeeper 中的目录节点权限不具有传递性,父目录节点的权限不能传递给子目录节点。目录节点 ACL 由两部分组成:perms 和 id。 Perms 有 ALL、READ、WRITE、CREATE、DELETE、ADMIN 几种 而 id 标识了访问目录节点的身份列表,默认情况下有以下两种: ANYONE_ID_UNSAFE = new Id("world", "anyone") 和 AUTH_IDS = new Id("auth", "") 分别表示任何人都可以访问和创建者拥有访问权限。 |
<> ( path, stat) | 获取某个目录节点的访问权限列表 |
4、同步调用和异步调用
这里记录一个创建节点的例子来说明同步调用和异步调用的使用。
同步调用:
String path = "/poype_node"; String nodePath = zooKeeper.create(path, "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
异步调用:
String path = "/poype_node2"; zooKeeper.create(path, "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() { public void processResult(int resultCode, String path, Object ctx, String name) { System.out.println(resultCode); System.out.println(path); System.out.println(ctx); System.out.println(name); } }, "创建");
在使用ZooKeeper的原生API时,经常需要处理几个问题:重复注册watcher、session失效重连、异常处理。
要解决上述的几个问题,可以自己解决,也可以采用第三方的java客户端来完成。一种常用的客户端zkclient,目前已经运用到了很多项目中,知名的有Dubbo、Kafka、Helix,关于zkclient下一节将进行介绍。
参考:
zookeeper java api介绍 https://segmentfault.com/a/1190000012262940
Zookeeper 使用https://www.cnblogs.com/mustone/p/7373671.html
关于zookeeper第三方客户端zkclient的使用说明https://blog.csdn.net/sun_wangdong/article/details/77461108
发表评论
最新留言
关于作者
