zookeeper使用
一、依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.3</version>
</dependency>
二、配置初始化bean
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooKeeper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.apache.zookeeper.Watcher;
import org.springframework.stereotype.Component;
import java.util.concurrent.CountDownLatch;
@Component
public class ZookeeperConfig {
@Value("${zookeeper.address}")
private String connectString;
@Value("${zookeeper.timeout}")
private int timeout;
@Bean(name = "zkClient")
public ZooKeeper zkClient() {
ZooKeeper zooKeeper = null;
try {
final CountDownLatch countDownLatch = new CountDownLatch(1);
//连接成功后,会回调watcher监听,此连接操作是异步的,执行完new语句后,直接调用后续代码
// 可指定多台服务地址 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
zooKeeper = new ZooKeeper(connectString, timeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
//如果收到了服务端的响应事件,连接成功
countDownLatch.countDown();
}
}
});
countDownLatch.await();
System.out.println("【初始化ZooKeeper连接状态....】={}"+zooKeeper.getState());
} catch (Exception e) {
System.out.println("初始化ZooKeeper连接异常....】={}"+ e);
}
return zooKeeper;
}
}
三、使用
1.增(创建节点)
public String create(String path, byte[] data, List<ACL> acl, CreateMode createMode, Stat stat, long ttl)
- path:节点路径
- data:节点数据
- acl:节点权限列表
- createMode:节点类型。临时/持久,是否设置过期时间。
- 节点状态:版本号、时间戳等参数。
- ttl:节点删除时间,0表示没有ttl。
@GetMapping("/create")
public R create(@RequestBody ZookeeperCreateVo zookeeperCreateVo) throws InterruptedException, KeeperException {
Stat stat = new Stat();
try {
zkClient.create(zookeeperCreateVo.getPath(), zookeeperCreateVo.getData().getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
return R.ok(String.format("创建成功,{%s},{%s}",zookeeperCreateVo.getPath(),zookeeperCreateVo.getData()));
} catch (Exception e) {
return R.error(String.format("创建持久化节点异常,{%s},{%s},{%s}",zookeeperCreateVo.getPath(),zookeeperCreateVo.getData(),e));
}
}
常见异常:如节点已存在、父节点不存在、客户端没有权限等
2. 改(修改节点数据)
public void setData(String path, byte[] data, int version, AsyncCallback.StatCallback cb, Object ctx)
- path:节点路径
- data:节点数据
- version:核对版本号,-1可跳过版本号检测
- StatCallback 回调函数
- ctx:回调参数,会在回调时携带给StatCallback
@GetMapping("/change")
public void change(@RequestBody ZookeeperChangeVo zookeeperChangeVo) throws InterruptedException, KeeperException {
zkClient.setData(zookeeperChangeVo.getPath(), zookeeperChangeVo.getData().getBytes(), -1, new AsyncCallback.StatCallback() {
@Override
public void processResult(int i, String s, Object o, Stat stat) {
System.out.println(o.toString());
}
},"回调参数");
}
3.查(监听/获取节点数据)
public void getData(String path, Watcher watcher, AsyncCallback.DataCallback cb, Object ctx)
- path:节点路径
- watcher:设置监听,节点修改时通知。设null不通知。
- DataCallback :查出后回调
- ctx:回调参数
@GetMapping("/listen")
public void listen(@RequestBody String path) throws InterruptedException, KeeperException {
String s = "";
zkClient.getData(path, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent.toString());
}
}, new AsyncCallback.DataCallback() {
@Override
public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
System.out.println(new String(bytes));
System.out.println(o.toString());
}
}, "回调参数");
}
4.删(删除节点)
public void delete(String path, int version, AsyncCallback.VoidCallback cb, Object ctx)
- path:节点路径
- version: 节点的数据版本,乐观锁,-1不匹配
- VoidCallback:回调函数
- ctx:回调参数
@GetMapping("/delete")
public void delete(@RequestBody String path) throws InterruptedException, KeeperException {
zkClient.delete(path, -1, new AsyncCallback.VoidCallback() {
@Override
public void processResult(int i, String s, Object o) {
System.out.println(o.toString());
}
},"回调参数");
}
5.子节点监听
子节点监听只监听子节点的增加和删除,不监听修改
public List<String> getChildren(String path, Watcher watcher)
- path:路径
- watcher:设置监听,节点修改时通知。设null不通知。
@GetMapping("/getChildren")
public List<String> getChildren(@RequestBody String path) throws InterruptedException, KeeperException {
List<String> children = zkClient.getChildren(path, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent.toString());
}
});
return children;
}