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 {
}
});
}
}