深入理解Zookeeper
Zookeeper本质上是提供一种集中式存储服务,可以作为注册中心,将服务地址注册在Zookeeper中以暴露给其他微服务,也可以作为统一的配置信息管理中心,利用Zookeeper的Watch机制可以实现对配置信息修改事件的监听并实时更新系统内已加载的配置项
第一,首先安装zkUI开源框架实时查看zookeeper中的数据
具体安装过程可以参考这篇博客:
https://www.cnblogs.com/zhangchengzi/p/10907595.html
第二步,结合SpringBoot完成配置管理中心
(1)引入pom依赖
<!--java zookeeper 客户端-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
<!--java zookeeper 客户端-->
(2)applicationContext.yml中配置Zookeeper节点
spring:
config:
zookeeper:
url: 10.212.130.44:12181,10.212.130.46:12181,10.212.130.47:12181
nodename: pay-server-config
(3)实现加载并监听系统配置文件的SystemConfigUtils
package com.bdcloud.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.RetryOneTime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.persistence.Column;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@Slf4j
public class SystemConfigUtils {
private Properties properties = new Properties();
@Value("${spring.config.zookeeper.url}")
private String zkUrl;
@Value("${spring.config.zookeeper.nodename}")
private String nodeName;
/***
* 执行类初始化
*/
@PostConstruct
public void initProperties() throws Exception {
Map<String,String> map = new HashMap<>();
//初始化zkClient连接客户端
CuratorFramework zkClient = CuratorFrameworkFactory.newClient(zkUrl, new RetryOneTime(1000));
zkClient.start(); //启动与kafka的连接
List<String> childList = zkClient.getChildren().forPath("/" + nodeName);
//遍历获取zookeeper中的所有数据
for (String childName:
childList) {
byte[] bytes = zkClient.getData().forPath("/" + nodeName + "/" + childName);
map.put(childName,new String(bytes));
}
log.info("初始化pay-server-config完毕");
this.properties.putAll(map);
//设置监听所有配置文件修改
TreeCache treeCache = new TreeCache(zkClient, "/" + nodeName);
treeCache.start();
treeCache.getListenable().addListener(new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
//接收到数据通知变化
switch (treeCacheEvent.getType()){
case NODE_UPDATED:
//接收到数据改变事件,并获取key
String key = treeCacheEvent.getData().getPath().replace("/" + nodeName + "/", "");
//获取更新的值
byte[] nowValue = treeCacheEvent.getData().getData();
if (nowValue!=null)
properties.setProperty(key,new String(nowValue));
default:
break;
}
}
});
}
}