准备

依赖

使用Curator,是目前使用者最多的zookeeper客户端

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>

配置类

curator需要我们自己配置一个CuratorFramework

1
2
3
4
5
6
7
8
9
10
@Configuration
public class ZookeeperConfig {

@Bean(initMethod = "start")//initMethod表示在Bean创建好后需要执行start的命令
public CuratorFramework curatorFramework(){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
return CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
}

}

操作代码

实现类

zookeeper的每条命令curator都有单独的方法对应,需要设置的参数curator也都设置了单独的方法,比如set -v version,curator可以使用setData().setData().withVersion(version)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@Service
public class ZookeeperService {

private Logger logger = LoggerFactory.getLogger(ZookeeperService.class);

@Autowired
private CuratorFramework client;

//create对应zookeeper create命令,withMode对应(-s:-e),代表有序/无序节点;临时/持久节点
public void creatNode(String path, String data) throws Exception {
client.create().withMode(CreateMode.PERSISTENT).forPath(path, data.getBytes(StandardCharsets.UTF_8));
}

//getData对应zookeeper get命令
public String getNode(String path) throws Exception {
byte[] data = client.getData().forPath(path);
return new String(data);
}


//setData对应zookeeper set命令,withVersion()对应-v 设置版本要求
public void setNode(String path, String newData, int version) throws Exception {
client.setData().withVersion(version).forPath(path, newData.getBytes(StandardCharsets.UTF_8));
}


//delete对应zookeeper delete命令,deletingChildrenIfNeeded()对应deleteall,withVersion()对应-v 设置版本要求
public void deleteNode(String path,int version) throws Exception {
client.delete().deletingChildrenIfNeeded().withVersion(version).forPath(path);
}

//watchers().add() 对应zookeeper addWatch命令,withMode()对应-m 决定采取哪种模式
public void addWatch(String path) throws Exception {
client.watchers().add().withMode(AddWatchMode.PERSISTENT).usingWatcher((CuratorWatcher) watchedEvent -> logger.info("{}",watchedEvent)).forPath(path);
}

//curator的缓存机制,利用本地缓存与zookeeper的数据对比实现监听
public void addWatch1(String path){
CuratorCache curatorCache = CuratorCache.build(client, path);
curatorCache.listenable().addListener((type, childData, childData1) -> {
switch (type){
case NODE_CREATED:
logger.info("创建节点:\n{}------{}",childData1.getPath(),new String(childData1.getData()));
break;
case NODE_CHANGED:
logger.info("节点改变:\n{}------{}\n{}------{}",childData.getPath(),new String(childData.getData()),childData1.getPath(),new String(childData1.getData()));
break;
case NODE_DELETED:
logger.info("节点删除:\n{}------{}",childData.getPath(),new String(childData.getData()));
break;
}
});
//新建完缓存后,一定要启动,否则不会生效
curatorCache.start();
logger.info("为{}添加watch成功",path);
}
}

Backgroundable接口

   Backgroundable 接口中定义了多个方法,最常用的是 inBackground() 方法,它表示将当前的操作放在后台线程中执行,即异步执行。inBackground() 方法有多个重载形式,其中最简单的形式不需要传入任何参数,表示后台任务执行完成后,不需要回调任何方法。  

  如果需要在后台任务完成后执行回调方法,可以使用inBackground(org.apache.curator.framework.api.BackgroundCallback callback) 方法。该方法需要传入一个 BackgroundCallback 接口的实现对象,该接口中定义了 processResult() 方法,用于在后台任务执行完成后处理结果。
  如果需要在后台任务完成后同时设置回调方法和自定义的 Executor,可以使用 inBackground(BackgroundCallback callback, java.util.concurrent.Executor executor) 方法。其中,Executor 对象表示后台任务执行所使用的线程池,通过它可以控制后台任务的执行。如果不指定 Executor,则会使用默认的线程池。
  Curator 框架的许多操作都支持后台异步执行,可以通过 inBackground() 方法指定。在使用 Curator 进行开发时,可以根据实际情况选择同步或异步操作。如果需要执行一些比较耗时的操作,最好采用异步方式,避免阻塞应用程序的主线程。


本站总访问量:次本站总访问数:人
本站由 Peng Tong 使用 Stellar 1.29.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。