1、引入相关依赖
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.12</lombok.version>
<zookeeper.version>3.6.0</zookeeper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
2、连接配置
@Configuration
public class ZookeeperConfig {
private static final Logger logger = LoggerFactory.getLogger(ZookeeperConfig.class);
@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语句后,直接调用后续代码
zooKeeper = new ZooKeeper(connectString, timeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
logger.info("receive event:" + event.toString());
if(Event.KeeperState.SyncConnected==event.getState()){
//如果收到了服务端的响应事件,连接成功
countDownLatch.countDown();
}
}
});
countDownLatch.await();
logger.info("【初始化ZooKeeper连接状态....】={}",zooKeeper.getState());
}catch (Exception e){
logger.error("初始化ZooKeeper连接异常....】={}",e);
}
return zooKeeper;
}
}
3、测试zookeeper的api
@Slf4j
@Component
public class ZnodeTest implements CommandLineRunner {
@Autowired
private ZooKeeper zkClient;
@Override
public void run(String... args) throws Exception {
List<String> children = zkClient.getChildren("/test1", new CustomWatcher());
log.info("children: "+ children);
if(!ObjectUtils.isEmpty(children)){
for (int i = 0; i < children.size(); i++) {
byte[] data = zkClient.getData("/test1/" + children.get(i), false, null);
if (data != null) {
log.info("get child "+"/test1/"+children.get(i)+":"+new String(data));
}else{
log.info("get child "+"/test1/"+children.get(i)+":"+null);
}
}
}
}
}
@Slf4j
public class CustomWatcher implements Watcher {
@Override
public void process(WatchedEvent watchedEvent) {
log.info(watchedEvent.toString());
}
}
Zookeeper中还有创建znode、删除znode、判断是否存在等api,就不一个一个去试了。
4、Apache Curator
连接zookeeper的java客户端还有一种叫curator。
增加依赖
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
properties中增加
<curator.version>4.3.0</curator.version>
curator方式配置连接
@Configuration
public class CuratorConfiguration {
@Value("${curator.retryCount}")
private int retryCount;
@Value("${curator.elapsedTimeMs}")
private int elapsedTimeMs;
@Value("${curator.connectString}")
private String connectString;
@Value("${curator.sessionTimeoutMs}")
private int sessionTimeoutMs;
@Value("${curator.connectionTimeoutMs}")
private int connectionTimeoutMs;
@Bean(initMethod = "start")
public CuratorFramework curatorFramework() {
return CuratorFrameworkFactory.newClient(
connectString,
sessionTimeoutMs,
connectionTimeoutMs,
new RetryNTimes(retryCount, elapsedTimeMs));
}
}
application.properties中增加
#重试次数
curator.retryCount=5
#重试间隔时间
curator.elapsedTimeMs=5000
# zookeeper 地址
curator.connectString=127.0.0.1:2181
# session超时时间
curator.sessionTimeoutMs=60000
# 连接超时时间
curator.connectionTimeoutMs=5000
测试API
@Slf4j
@Component
public class CuratorZnodeTest implements CommandLineRunner {
@Autowired
private CuratorFramework zkClient;
@Override
public void run(String... args) throws Exception {
GetChildrenBuilder children = zkClient.getChildren();
log.info("get children by Curator:"+children.forPath("/test1"));
}
}
5、Java客户端的选择
Zookeeper原生Java API、ZKClient和Apache Curator 区别对比
参考
SpringBoot集成Zookeeper
缓存架构SpringBoot集成Curator实现zookeeper分布式锁