这个只能获取单个,想获取所有节点的
想实现的是通过监听所有节点,获取所有providers的信息
@Nervermore10086: 实现了吗?也需要这块代码逻辑,能参考下吗
@publicName: package com.daydao.dubbo.rest.gateway.zookeeper;
import com.daydao.dubbo.rest.gateway.properties.ZookeeperProperties;
import com.daydao.dubbo.rest.gateway.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
参考文章
*/
@Configuration
@Slf4j
public class DistributeClient implements Watcher {
private ZookeeperProperties zookeeperProperties;
//zookeeper连接
private ZooKeeper zkClient;
/**
public DistributeClient(){
try {
zookeeperProperties = SpringContextHolder.getBean(ZookeeperProperties.class);
// 获取 zookeeper 集群连接
zkClient = new ZooKeeper(zookeeperProperties.getUrl(), zookeeperProperties.getSessionTimeout(), this);
// 注册监听
getChildren();
}catch (Exception e){
log.error("初始化失败:{0}",e);
}
}
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.Expired) {
try {
zkClient = new ZooKeeper(zookeeperProperties.getUrl(), zookeeperProperties.getSessionTimeout(), this);
} catch (IOException e) {
log.warn("fail to connect to zoo keeper", e);
}
}else{
try {
getChildren();
}catch (Exception e){
log.error("监听ZK节点异常:{}",e);
}
}
}
/**
获取所有dubbo下面的rest服务相关信息
@throws KeeperException
@throws InterruptedException
*/
private void getChildren() throws KeeperException, InterruptedException {
//返回给定路径的节点的统计信息。 如果没有,则返回null
if (zkClient.exists("/dubbo", false) == null) {
zkClient.create("/dubbo", "server".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
// 监听 /dubbo 节点
List<String> children = zkClient.getChildren("/dubbo", true);
Map<String, Set<ApplicationNetInfo>> searchRestProviders = new ConcurrentHashMap<>();
for (String child : children) {
// 获取/dubbo节点下面的所有的服务提供者
List<String> listProvider = zkClient.getChildren("/dubbo/" + child + "/providers", true, null);
Iterator<String> itListProvider = listProvider.iterator();
while (itListProvider.hasNext()) {
String zkInfo = itListProvider.next();
//只筛选rest服务
if (zkInfo.startsWith("rest")) {
zkInfo = zkInfo.replaceAll("%3A", ":").replaceAll("%2F", "/") //过滤URL 包含中文
.replaceAll("%3F", "?").replaceAll("%3D", "=").replaceAll(
"%26", "&");
String application = getApplication(zkInfo);
//进行去重的判断(可能存在重复的信息,相同的信息只保存一次即可)
if(searchRestProviders.get(application) == null)
searchRestProviders.put(application,new HashSet<ApplicationNetInfo>());
searchRestProviders.get(application).add(ApplicationNetInfo.builder().application(application).ip(getIP(zkInfo)).port(getPort(zkInfo)).build());
}
itListProvider.remove();
}
}
//更新缓存,后期还可以优化,不用批量更新
restProviders = searchRestProviders;
}
/**
/**
/**
/**
}
@Nervermore10086: 非常感谢您