Zookeeper之ZKClient的使用

本文介绍了如何在Spring Boot项目中使用Maven引入zkclient库,并展示了如何配置Zookeeper客户端,监听路径变化及刷新缓存的实际应用。涵盖了Zookeeper连接、数据监听和基本操作实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

maven依赖 


<dependency>  
    <groupId>com.101tec</groupId>  
    <artifactId>zkclient</artifactId>  
    <version>0.4</version>  
</dependency>

demo

package org.zk;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.springframework.beans.factory.annotation.Value;

public abstract class BaseCacheManager {

    /**
     * ZK客户端
     */
    protected ZkClient zkClient;

    /**
     * 监控ZK路径
     */
    protected String watchPath;

    protected String basePath = "app";

    @Value("${zk.address:zookeeper://127.0.0.1:2181}")
    private String zkAddress;


    protected void initZk() {
        zkAddress = zkAddress.replaceAll("zookeeper://", "").replaceAll("\\?backup=", ",");
        zkClient = new ZkClient(zkAddress, 10000, 100000, new SerializableSerializer());
        watchPath = getWatchPath();
        if (!zkClient.exists(watchPath)) {
            zkClient.createPersistent(watchPath);
        }
        zkClient.subscribeDataChanges(watchPath, buildListener());
    }

    /**
     * 获取监听路径
     *
     * @return ZK监听路径
     */
    public abstract String getWatchPath();

    /**
     * 变更处理监听类
     *
     * @return 监听类
     */
    public abstract IZkDataListener buildListener();
}
package org.zk;

import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.IZkDataListener;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class DemoCacheManager extends BaseCacheManager implements InitializingBean {

    /**
     * demo目录
     */
    private static final String DEMO_PATH = "/demo";

    public static Map<String, String> map = new ConcurrentHashMap<>();


    @Override
    public void afterPropertiesSet() {
        initZk();
        log.info("初始化完成");
    }

    /**
     * 刷新缓存,其实就是变更Zookeeper路径下的值
     */
    public synchronized void refreshCache() {
        zkClient.writeData(watchPath, DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
    }

    @Override
    public String getWatchPath() {
        return "/" + basePath + DEMO_PATH;
    }

    @Override
    public IZkDataListener buildListener() {
        return new IZkDataListener() {

            @Override
            public void handleDataChange(String dataPath, Object data) {
                log.info("数据发生变化,重新刷新缓存。", data);
                loadData();
            }

            @Override
            public void handleDataDeleted(String dataPath) {

            }
        };
    }

    private void loadData() {
        map.put("demo", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
    }

}

测试:

package org.zk;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TestJob {

    @Autowired
    private DemoCacheManager  demoCacheManager;

    @Scheduled(cron = "*/5 * * * * ?")
    public void cronJob() {
        demoCacheManager.refreshCache();
    }


}

参考:

Zookeeper之ZKClient的使用

package org.zk;

import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.util.ArrayList;
import java.util.List;

public class ZooUtil {


    public static void main(String[] args) {
        List<String> ll = new ArrayList<String>();
        ZkClient zkClient = new ZkClient("172.16.10.107:2181", 3000, 3000, new SerializableSerializer());
        /**
         * 获取子目录下的数据
         */
        List<String> l = zkClient.getChildren("/");
        for (String s : l) {
            System.out.println(s);
        }
        
        /**
         * 创建节点
         */
        zkClient.createPersistent("/test1");
        
        /**
         * 创建子节点
         */
        zkClient.createPersistent("/test1/test", true);
        
        /**
         * 创建并设置节点的值
         */
        zkClient.createPersistent("/test1", "aaaa");
        
        /**
         * 写数据,即更新数据,会update,不会append
         */
        zkClient.writeData("/test1", "hello");
        
        /**
         * 写一个对象,要序列化
         */
        User user = new User();
        user.setId(1);
        user.setName("bbbb");
        zkClient.create("/test1", user, CreateMode.PERSISTENT);
        
        /**
         * 删除节点
         */
        zkClient.delete("/test1");
        
        /**
         * 递归删除节点和其子节点
         */
        zkClient.deleteRecursive("/test1");

        /**
         * 读取数据对象
         */
        Stat stat = new Stat();
        User u = zkClient.readData("/test1", stat);
        System.out.println(u.getName());
        
        /**
         * 读取简单类型数据
         */
        String s = zkClient.readData("/test1");
        System.out.println(s);

        /**
         * 判断节点是否存在
         */
        boolean b = zkClient.exists("/test1");

        /**
         * 监听节点的变化,节点增加,删除,减少
         */
        zkClient.subscribeChildChanges("/test1", new IZkChildListener() {
            @Override
            public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                System.out.println("parentPath = " + parentPath);

            }
        });
        /**
         * 监听节点数据的变化,子节点数据变化不会监听到
         */
        zkClient.subscribeDataChanges("/test1", new IZkDataListener() {
            //数据变化时触发
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {

            }

            //节点删除时触发
            @Override
            public void handleDataDeleted(String dataPath) throws Exception {

            }
        });
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值