zoukankan      html  css  js  c++  java
  • Ribbon监听Nacos注册中心服务变化并刷新服务地址列表

    com.netflix.loadbalancer.DynamicServerListLoadBalancer
    中 updateListOfServers()方法 用于从注册中心刷新服务列表 
    @VisibleForTesting
        public void updateListOfServers() {
            List<T> servers = new ArrayList<T>();
            if (serverListImpl != null) {
                servers = serverListImpl.getUpdatedListOfServers();
                LOGGER.debug("List of Servers for {} obtained from Discovery client: {}",
                        getIdentifier(), servers);
    
                if (filter != null) {
                    servers = filter.getFilteredListOfServers(servers);
                    LOGGER.debug("Filtered List of Servers for {} obtained from Discovery client: {}",
                            getIdentifier(), servers);
                }
            }
            updateAllServerList(servers);
        }
    

    封装在 ServerListUpdater.UpdateAction对象中
     protected final ServerListUpdater.UpdateAction updateAction = new ServerListUpdater.UpdateAction() {
            @Override
            public void doUpdate() {
                updateListOfServers();
            }
        };
    
    UpdateAction 可以从 PollingServerListUpdater 中拿到,所以需要自定义 ServerListUpdater 类继承  PollingServerListUpdater ,注入并替换默认的PollingServerListUpdater
     @Bean
        @ConditionalOnMissingBean
        public ServerListUpdater ribbonServerListUpdater(IClientConfig config) {
            return new PollingServerListUpdater(config);
        }
    
        @Bean
        @ConditionalOnMissingBean
        public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerList<Server> serverList, ServerListFilter<Server> serverListFilter, IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
            return (ILoadBalancer)(this.propertiesFactory.isSet(ILoadBalancer.class, this.name) ? (ILoadBalancer)this.propertiesFactory.get(ILoadBalancer.class, config, this.name) : new ZoneAwareLoadBalancer(config, rule, ping, serverList, serverListFilter, serverListUpdater));
        }
    

     

     具体操作如下:

    @Component("ribbonServerListUpdater")
    public class MyPollingServerListUpdater extends PollingServerListUpdater {
    
        private UpdateAction updateAction;
    
        @Override
        public synchronized void start(UpdateAction updateAction) {
    
            this.updateAction = updateAction;
    
            super.start(updateAction);
    
        }
    
    
        public UpdateAction getUpdateAction(){
    
            return updateAction;
    
        }
    }

    定义Nacos监听器并调用 updateAction.doUpdate() 方法

    @Component
    public class ServerStatusListner {
    
        @Autowired
        private MyPollingServerListUpdater myListUpdater;
    
        @Value("${spring.cloud.nacos.discovery.namespace}")
        private String namespace;
        @Value("${spring.cloud.nacos.discovery.server-addr}")
        private String serverAddr;
    
        @PostConstruct
        public void init() throws Exception {
    
            //初始化监听服务上下线
    
            Properties properties = System.getProperties();
            properties.put(PropertyKeyConst.NAMESPACE, namespace);
            properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
    
            NamingService naming = NamingFactory.createNamingService(properties);
    
            List<String> serviceNames = new ArrayList<>();
            // 要监听的服务名称
            serviceNames.add("SVC1");
            serviceNames.add("SVC2");
            serviceNames.stream().forEach(serviceName->{
    
                try {
    
                    naming.subscribe(serviceName, (event -> {
                        //通知ribbon更新服务列表
                        ServerListUpdater.UpdateAction updateAction = myListUpdater.getUpdateAction();
    
                        if (updateAction != null){
                            updateAction.doUpdate();
                        }
    
                        NamingEvent namingEvent = (NamingEvent) event;
    
                        List<Instance> instances = namingEvent.getInstances();
    
                        String name = namingEvent.getServiceName();
    
                        if(instances != null && !instances.isEmpty()){
    
                            instances.stream().forEach(instance -> {
    
                                System.out.println("服务"+name+":"+instance);
                            });
                        }else {
                            System.out.println("服务"+name+"列表为空");
                        }
                    }));
    
                } catch (NacosException e) {
                    e.printStackTrace();
                }
            });
        }
    }


     

  • 相关阅读:
    AOP 相关包
    Dubbo学习(一) Dubbo原理浅析
    maven 三个仓库表
    关于servlet中doGet和doPost乱码再一次理解
    关于对String中intern方法的理解
    模拟文件上传(五):为文件添加描述信息
    模拟文件上传(四):对于前面三版中一些出错细节进行处理
    对于模拟文件上传(三)中,批量上传,传空值抛异常前台约束实现
    模拟文件上传(三):使用apache fileupload组件进行文件批量上传
    模拟文件上传(二):使用apache fileupload组件进行文件上传
  • 原文地址:https://www.cnblogs.com/nihaoyueyue/p/14377972.html
Copyright © 2011-2022 走看看