首页 新闻 搜索 专区 学院

如何获取dubbo服务注册到zookeeper中的所有providers的信息

0
悬赏园豆:100 [已解决问题] 解决于 2019-11-06 14:22

如何获取dubbo服务注册到zookeeper中的所有providers的信息

Nervermore10086的主页 Nervermore10086 | 初学一级 | 园豆:143
提问于:2019-11-06 11:43
< >
分享
最佳答案
0

https://www.cnblogs.com/jhxxb/p/10759851.html 这篇文章应该是给出了答案

Nervermore10086 | 初学一级 |园豆:143 | 2019-11-06 14:18
其他回答(1)
0
收获园豆:100
| 园豆:391 (菜鸟二级) | 2019-11-06 11:49

这个只能获取单个,想获取所有节点的

支持(0) 反对(0) Nervermore10086 | 园豆:143 (初学一级) | 2019-11-06 11:50

想实现的是通过监听所有节点,获取所有providers的信息

支持(0) 反对(0) Nervermore10086 | 园豆:143 (初学一级) | 2019-11-06 11:51

@Nervermore10086: 实现了吗?也需要这块代码逻辑,能参考下吗

支持(0) 反对(0) publicName | 园豆:200 (初学一级) | 2020-06-08 17:42

@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;

/**

  • 参考文章

  • https://www.cnblogs.com/jhxxb/p/10759851.html

  • http://zookeeper.apache.org/doc/r3.4.14/javaExample.html

  • https://my.oschina.net/u/164027/blog/1921308

  • */
    @Configuration
    @Slf4j
    public class DistributeClient implements Watcher {

    private ZookeeperProperties zookeeperProperties;

    //zookeeper连接
    private ZooKeeper zkClient;

    /**

    • 所有Rest服务提供者
      */
      public static Map<String, Set<ApplicationNetInfo>> restProviders = new ConcurrentHashMap<>();

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

    /**

    • 截取
    • @param str
    • @return
      */
      private String getIP(String str){
      String[] split = str.split("//");
      return split[1].split("😊[0];
      }

    /**

    • 截取port
    • @param str
    • @return
      */
      private String getPort(String str){
      String[] split = str.split("//");
      return split[1].split("😊[1].split("/")[0];
      }

    /**

    • 截取application
    • @param str
    • @return
      */
      private String getApplication(String str){
      String application = "";
      String[] split = str.split("&");
      for (String item:split) {
      if (item.startsWith("application")){
      application = item.split("=")[1];
      break;
      }
      }
      return application;
      }

    /**

    • 返回所有rest服务信息
    • @return
      */
      public Map<String, Set<ApplicationNetInfo>> getApplicationNetInfos(){
      return restProviders;
      }

}

支持(0) 反对(0) Nervermore10086 | 园豆:143 (初学一级) | 2020-06-08 17:44

@Nervermore10086: 非常感谢您

支持(0) 反对(0) publicName | 园豆:200 (初学一级) | 2020-06-09 10:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册