设置更改配置信息写入zookeeper,同时通知各个客户端更新配置信息到jvm 缓存。获取配置信息从jvm缓存获取。
一:pom 依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency>
二:java 代码实现
监听类:
import com.alibaba.fastjson.JSON;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
public class ShopConfigListener implements PathChildrenCacheListener {
private ZkClient zkClient;
public ShopConfigListener(ZkClient zkClient) {
this.zkClient = zkClient;
}
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
switch(event.getType().ordinal()) {
case 0:
this.registerShopConfig(event);
break;
case 1:
this.registerShopConfig(event);
break;
case 2:
this.removeShopConfig(event);
break;
case 3:
//this.removeRouting(event);
break;
default:
break;
}
}
private void registerShopConfig(PathChildrenCacheEvent event) throws Exception {
String path = event.getData().getPath();
String config = zkClient.readWithPath(new String[]{path});
ShopConfigDomain shopConfigDomain = JSON.parseObject(config,ShopConfigDomain.class);
synchronized(ShopConfigService.class) {
ShopConfigService.shopConfig.put(zkClient.getShopID(path),shopConfigDomain);
}
}
private void removeShopConfig(PathChildrenCacheEvent event) throws Exception {
String path = event.getData().getPath();
ShopConfigService.shopConfig.remove(zkClient.getShopID(path));
}
}
zkclient 类:zk
import com.alibaba.fastjson.JSON;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.retry.RetryUntilElapsed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;
@Configuration
public class ZkClient {
private static final Logger log = LoggerFactory.getLogger(ZkClient.class);
@Autowired
public ZookeeperProperties zookeeperProperties;
private CuratorFramework curator;
private CuratorFramework newCurator(String zkServers) throws Exception {
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString(zkServers)
.retryPolicy(new RetryUntilElapsed(2147483647, 60000))
.connectionTimeoutMs(100000)
.sessionTimeoutMs(100000)
.build();
client.start();
return client;
}
@PostConstruct
public void initCuratorClient() throws Exception {
if (!this.zookeeperProperties.validateProperties()) {
throw new IllegalStateException("Properties config error!");
} else {
String zkServers = this.zookeeperProperties.getZkServer();
if (this.curator == null) {
this.curator = this.newCurator(zkServers);
}
}
String shopConfigPath = zookeeperProperties.getShopConfigPath()+"/"+this.zookeeperProperties.getAppName();
ShopConfigService.shopConfigPath = shopConfigPath;
if (checkExists(shopConfigPath)) {
List<String> childPath = getChildren(shopConfigPath);
if(null != childPath && childPath.size()>0){
for (String nodeName:childPath){
String chindNodePaht = shopConfigPath+"/"+nodeName;
putConfig(chindNodePaht);
}
}
}else{
write(shopConfigPath,"shopConfig");
}
registerShopConfigListenter(shopConfigPath);
}
public void putConfig(String childPath) throws Exception{
String config = readWithPath(new String[]{childPath});
ShopConfigDomain shopConfigDomain = JSON.parseObject(config,ShopConfigDomain.class);
synchronized(ZkClient.class) {
ShopConfigService.shopConfig.put(getShopID(childPath),shopConfigDomain);
}
}
public Integer getShopID(String path) {
String[] split = path.split("/");
if(split.length >= 5) {
return Integer.parseInt(split[5]);
} else {
throw new IllegalStateException("shopID is empty!");
}
}
public void setData(String path, String content)throws Exception {
this.curator.setData().forPath(path, content.getBytes("utf-8"));
}
public void set(String path, String content) throws Exception {
try {
if (this.curator.checkExists().forPath(path) == null) {
this.curator.create()
.creatingParentsIfNeeded()
.forPath(path, content.getBytes("utf-8"));
}
}catch (Exception e){
e.printStackTrace();
throw e;
}
}
public boolean checkExists(String path) throws Exception{
if (this.curator.checkExists().forPath(path) == null) {
return false;
}
return true;
}
public String read(String path) throws Exception {
if (this.curator.checkExists().forPath(path) == null) {
throw new IllegalArgumentException("Path content is empty, error!");
} else {
byte[] b = (byte[]) this.curator.getData().forPath(path);
String value = new String(b, "utf-8");
return value;
}
}
/**
* 获取子目录
*/
public List<String> getChildren(String path) throws Exception {
if (this.curator.checkExists().forPath(path) == null) {
return null;
} else {
List children = (List) this.curator.getChildren().forPath(path);
return children;
}
}
public void registerShopConfigListenter(String path) throws Exception {
PathChildrenCache childrenCache = new PathChildrenCache(this.curator, path, false);
ShopConfigListener shopConfigListener = new ShopConfigListener(this);
childrenCache.getListenable().addListener(shopConfigListener);
childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
}
public String readWithPath(String... paths) throws Exception {
if(paths.length == 0) {
return null;
} else {
String path = null;
String[] var3 = paths;
int var4 = paths.length;
for(int var5 = 0; var5 < var4; ++var5) {
String temp = var3[var5];
if(path == null) {
path = "/" + temp;
} else {
path = path + "/" + temp;
}
}
path = path.replaceAll("//", "/");
return this.read(path);
}
}
}