注意我这里用的是官方最稳定的版本3.7.1,版本之间有个别命令是有差距的!
本篇文章的示例SpringBoot和Zookeeper客户端以及zookeeper都是最新版本!
Curator是Netflix公司开源的⼀套zookeeper客户端框架,Curator是对Zookeeper⽀持最好的客户端框架。Curator封装了⼤部分Zookeeper的功能,⽐如Leader选举、分布式锁等,减少了技术⼈员在使⽤Zookeeper时的底层细节开发⼯作。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<groupId>com.gzl.cn</groupId>
<artifactId>spring-boot-curator-zk</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-curator-zk</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.1</version>
</dependency>
<!--Zookeeper-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<!--解决Spring Boot Configuration Annotation Processor not configured提示问题-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>4.12</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml和application.properties是都可以的,只不过他们的格式不一样。
curator:
#重试retryCount次,当会话超时出现后,curator会每间隔elapsedTimeMs毫秒时间重试一次,共重试retryCount次。
retryCount: 5
elapsedTimeMs: 5000
#服务器信息
connectString: 127.0.0.1:2181
#会话超时时间设置
sessionTimeoutMs: 60000
#连接超时时间
connectionTimeoutMs: 5000
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZK {
private int retryCount;
private int elapsedTimeMs;
private String connectString;
private int sessionTimeoutMs;
private int connectionTimeoutMs;
}
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CuratorConfig {
@Autowired
WrapperZK wrapperZk;
/**
* 这里的start就是创建完对象放到容器后,需要调用他的start方法
*
* @return
*/
@Bean(initMethod = "start")
public CuratorFramework curatorFramework() {
return CuratorFrameworkFactory.newClient(
wrapperZk.getConnectString(),
wrapperZk.getSessionTimeoutMs(),
wrapperZk.getConnectionTimeoutMs(),
new RetryNTimes(wrapperZk.getRetryCount(), wrapperZk.getElapsedTimeMs()));
}
}
在这里添加测试方法即可!
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootCuratorZkApplication.class)
class SpringBootCuratorZkApplicationTests {
@Autowired
CuratorFramework curatorFramework;
/**
* 创建节点
*
* @throws Exception
*/
@Test
void createNode() throws Exception {
// 添加持久节点
String path = curatorFramework.create().forPath("/curator-node");
System.out.println(String.format("curator create node :%s successfully.", path));
// 添加临时序号节点,并赋值数据
String path1 = curatorFramework.create()
.withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath("/curator-node", "some-data".getBytes());
System.out.println(String.format("curator create node :%s successfully.", path));
// System.in.read()目的是阻塞客户端关闭,我们可以在这期间查看zk的临时序号节点
// 当程序结束时候也就是客户端关闭的时候,临时序号节点会消失
System.in.read();
}
/**
* 获取节点
*
* @throws Exception
*/
@Test
public void testGetData() throws Exception {
// 在上面的方法执行后,创建了curator-node节点,但是我们并没有显示的去赋值
// 通过这个方法去获取节点的值会发现,当我们通过Java客户端创建节点不赋值的话默认就是存储的创建节点的ip
byte[] bytes = curatorFramework.getData().forPath("/curator-node");
System.out.println(new String(bytes));
}
/**
* 修改节点数据
*
* @throws Exception
*/
@Test
public void testSetData() throws Exception {
curatorFramework.setData().forPath("/curator-node", "changed!".getBytes());
byte[] bytes = curatorFramework.getData().forPath("/curator-node");
System.out.println(new String(bytes));
}
/**
* 创建节点同时创建⽗节点
*
* @throws Exception
*/
@Test
public void testCreateWithParent() throws Exception {
String pathWithParent = "/node-parent/sub-node-1";
String path = curatorFramework.create().creatingParentsIfNeeded().forPath(pathWithParent);
System.out.println(String.format("curator create node :%s successfully.", path));
}
/**
* 删除节点(包含子节点)
*
* @throws Exception
*/
@Test
public void testDelete() throws Exception {
String pathWithParent = "/node-parent";
curatorFramework.delete().guaranteed().deletingChildrenIfNeeded().forPath(pathWithParent);
}
}
上面那个闪电意思是install的时候跳过maven测试阶段,之所以要跳过测试阶段是因为假如不跳过他会验证测试方法,例如我们创建节点的方法,有时候我们节点已经创建了,但是他还会验证,所以就会报错。