在分布式环境下如何让多个jvm进程内共享数据?
通过zookeeper简单实现
环境:zookeeper3.6.2+springboot2.2.10
pom.xml
<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>
</dependency>
</dependencies>
application.yml
server:
port: 9881
---
zk:
connectString: localhost:2181,localhost:2182,localhost:2183
timeout: 3000
config:
path: /config/ids
配置类
@Configuration
public class ZKConfig {
private static Logger logger = LoggerFactory.getLogger(ZKConfig.class) ;
@Value("${zk.connectString}")
private String connectString ;
@Value("${zk.timeout}")
private Integer timeout ;
@Bean
public ZooKeeper zookeeper() {
ZooKeeper zookeeper = null;
try {
CountDownLatch cdl = new CountDownLatch(1);
logger.info("zk准备连接: {}", connectString) ;
zookeeper = new ZooKeeper(connectString, timeout, event -> {
if (event.getState() == Event.KeeperState.SyncConnected) {
logger.info("zk服务器连接成功");
cdl.countDown() ;
}
}) ;
cdl.await() ;
} catch(Exception e) {
e.printStackTrace() ;
}
return zookeeper ;
}
@Configuration
public static class WatchNodeData implements InitializingBean {
public static Set<String> cache = new HashSet<>() ;
@Resource
private ZooKeeper zk ;
@Value("${zk.config.path}")
private String path ;
@Override
public void afterPropertiesSet() throws Exception {
if (zk.exists(path, null) == null) {
zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT) ;
}
// PERSISTENT是不监听子孙节点,PERSISTENT_RECURSIVE是递归监听子孙节点
zk.addWatch(path, new NodeIdWatch(zk), AddWatchMode.PERSISTENT_RECURSIVE) ;
}
private static class NodeIdWatch implements Watcher {
private ZooKeeper zk ;
public NodeIdWatch(ZooKeeper zk) {
this.zk = zk ;
}
@Override
public void process(WatchedEvent event) {
switch (event.getType()) {
case NodeDataChanged:
try {
String val = new String(this.zk.getData(event.getPath(), false, null)) ;
logger.info("节点{} 数据发生变化, 当前值:{}", event.getPath(), val);
WatchNodeData.cache.add(val) ;
} catch (Exception e) {
e.printStackTrace();
}
break ;
case NodeCreated:
logger.info("创建了节点:{}", event.getPath());
break ;
case NodeChildrenChanged:
logger.info("子节点发生了变化:{}", event.getPath());
break;default:
break;
}
}
}
}
}
这样我们监听节点数据的变化即可,只要有变化就添加到Set集合中。我们这里处理的小数据量可以这么玩,如果是海量数据肯定不能通过jvm来缓存数据。

至于zookeeper设置值,我们可以调用zk.setData即可,一旦设置了 我们这里就可以监听到,所以集群的服务都能收到。
完毕!!!







