zookeeper客戶端連接zk集羣

通用配置

  1. maven依賴
<properties>
	<java.version>1.8</java.version>
	<skipTests>true</skipTests>
</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>3.6.2</version>
		<exclusions>
			<exclusion>
				<groupId>org.slf4j</groupId>
				<artifactId>slf4j-log4j12</artifactId>
			</exclusion>
		</exclusions>
	</dependency>

	<!-- zkclient -->
	<dependency>
		<groupId>com.101tec</groupId>
		<artifactId>zkclient</artifactId>
		<version>0.11</version>
	</dependency>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
		<exclusions>
			<exclusion>
				<groupId>org.junit.vintage</groupId>
				<artifactId>junit-vintage-engine</artifactId>
			</exclusion>
		</exclusions>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<excludes>
					<exclude>
						<groupId>org.projectlombok</groupId>
						<artifactId>lombok</artifactId>
					</exclude>
					<exclude>
						<groupId>org.springframework.boot</groupId>
						<artifactId>spring-boot-configuration-processor</artifactId>
					</exclude>
				</excludes>
			</configuration>
		</plugin>
	</plugins>
</build>
  1. zookeeper的集羣配置 application.properties新增zk cluster的信息
# zk 集羣IP地址
zookeeper.cluster.hosts=10.211.55.5:2182,10.211.55.5:2183,10.211.55.5:2184,10.211.55.5:2185
zookeeper.cluster.sessionTimeout=5000

zk原生客戶端

import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

/**
 * zk原生客戶端測試
 */
@Slf4j
@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ZookeeperOriginalClientTest {

	@Value("${zookeeper.cluster.hosts}")
	private String hosts;

	@Value("${zookeeper.cluster.sessionTimeout}")
	private Integer sessionTimeout;

	private ZooKeeper zk;

	static class ZkOriginalWatcher implements Watcher {
		@Override
		public void process(WatchedEvent event) {
			log.info("watched event: {}",event);
			if (event.getState() == Event.KeeperState.SyncConnected){
				log.info("已連接");
			}
		}
	}

	@BeforeAll
	public void initZooKeeper()throws Exception{
		zk = new ZooKeeper(hosts,sessionTimeout,new ZkOriginalWatcher());
		log.info("init zk: {}",zk);
	}

	@Test
	public void testNode() throws Exception{
		String path = "/testnode/node2";
		// 是否存在
		Stat exists = zk.exists(path, true);
		log.info("path stat: {}",exists);

		// 創建節點
		String createRet = zk.create(path, "hello,zookeeper".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		log.info("createRet: {}",createRet);

		// 修改節點內容
		Stat stat = zk.setData(path, "world".getBytes(), -1);
		log.info("setData result: {}",stat);

		// 創建多個節點
		zk.create(path+"/snode1", "1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		zk.create(path+"/snode2", "1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		zk.create(path+"/snode3", "1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

		// 獲取所有子節點
		List<String> children = zk.getChildren(path, true);
		log.info("children: {}",children);

		// 刪除節點
		zk.delete(path+"/snode3",-1);

	}
}

zkClient客戶端

  • 支持遞歸創建node,遞歸刪除節點
  • session支持重連
  • 創建節點數據支持序列化

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.Serializable;
import java.util.List;
import java.util.concurrent.CountDownLatch;


/**
 * zkClient客戶端測試
 */
@Slf4j
@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ZkClientTests {

	@Value("${zookeeper.cluster.hosts}")
	private String hosts;

	private ZkClient client;

	@BeforeAll
	public void initClient(){
		client = new ZkClient(hosts);
		log.info("ZkClient已完成初始化!!!");
	}

	@Data
	@AllArgsConstructor
	static class User implements Serializable {
		private String username;
		private Integer age;
	}

	@Test
	public void createTestZkClient(){
		// 創建一個持久節點,值支持object
		client.create("/zkclientnode2",20,CreateMode.PERSISTENT);

		// 創建一個持久節點,可以遞歸創建節點,但無法遞歸設置值
		client.createPersistent("/zkclientnode/users/lisi",true);
		client.createPersistent("/zkclientnode/address/beijing",true);

		// 創建一個持久節點,序列化
		client.createPersistent("/zkclientnode/users/zhangsan",new User("張三",18));
	}

	@Test
	public void modifyTest(){
		// 讀取節點內容,不存在返回Null
		Object readDataBefore = client.readData("/zkclientnode2",true);
		log.info("readDataBefore value: {}",readDataBefore);

		// 修改節點內容
		client.writeData("/zkclientnode2","wirte data");
		Object readDataAfter = client.readData("/zkclientnode2",true);
		log.info("readDataAfter value: {}",readDataAfter);
	}

	@Test
	public void deleteTest(){
		// 普通刪除
		client.delete("/zkclientnode2");
		// 遞歸刪除
		client.deleteRecursive("/testnode");
//		client.create("/testnode",1,CreateMode.PERSISTENT);
	}

	@Test
	public void readTestZkClient(){
		List<String> children = client.getChildren("/zkclientnode/users");
		log.info("children: {}",children);

		children.forEach(nodeName ->{
			Object readData = client.readData("/zkclientnode/users/"+nodeName);
			log.info("batch read node: {}",readData);
		});
	}

	@Test
	public void watcherTest() throws InterruptedException {
		CountDownLatch countDownLatch = new CountDownLatch(1);
		client.subscribeDataChanges("/testnode", new IZkDataListener() {
			@Override
			public void handleDataChange(String dataPath, Object data) throws Exception {
				log.info("===========數據已發生改變! dataPath: {},data: {}==========",dataPath,data);
				countDownLatch.countDown();
			}

			@Override
			public void handleDataDeleted(String dataPath) throws Exception {
				log.info("===========數據已被刪除! dataPath: {}==========",dataPath);
				countDownLatch.countDown();
			}
		});

		Object readData = client.readData("/testnode");
		log.info("origin data: {}",readData);

		client.writeData("/testnode","899");
		client.deleteRecursive("/testnode");
		countDownLatch.await();
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章