forked from rongchao/epmet-cloud-rizhao
				
			
				 155 changed files with 6675 additions and 153 deletions
			
			
		| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,17 @@ | |||
| package com.epmet.dataaggre.constant; | |||
| 
 | |||
| /** | |||
|  * @Author zxc | |||
|  * @DateTime 2021/9/23 4:06 下午 | |||
|  * @DESC | |||
|  */ | |||
| public interface TDuckConstant { | |||
| 
 | |||
|     String CLIENT_GOV = "gov"; | |||
|     String CLIENT_RESI = "resi"; | |||
|      | |||
|     String ORG_TYPE_AGENCY = "agency"; | |||
|     String ORG_TYPE_GRID = "grid"; | |||
|     String ORG_TYPE_DEPT = "dept"; | |||
| 
 | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| package com.epmet.dataaggre.dto.epmettduck.result; | |||
| 
 | |||
| import lombok.Data; | |||
| 
 | |||
| @Data | |||
| public class PermissionValidateResultDTO { | |||
|     private Boolean permitted; | |||
|     private String accessKey; | |||
| } | |||
| @ -0,0 +1,19 @@ | |||
| package com.epmet.dataaggre.dto.epmettduck.result; | |||
| 
 | |||
| import lombok.Data; | |||
| 
 | |||
| import java.io.Serializable; | |||
| 
 | |||
| /** | |||
|  * @Description | |||
|  * @Author zhaoqifeng | |||
|  * @Date 2021/9/23 10:03 | |||
|  */ | |||
| @Data | |||
| public class RedPointResultDTO implements Serializable { | |||
|     private static final long serialVersionUID = -2230123089546481389L; | |||
|     /** | |||
|      * redPoint | |||
|      */ | |||
|     private String redPoint; | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.dataaggre.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| package com.epmet.dataaggre.service; | |||
| 
 | |||
| import com.epmet.dataaggre.dto.epmettduck.result.PermissionValidateResultDTO; | |||
| 
 | |||
| public interface QuestionnaireService { | |||
|     PermissionValidateResultDTO resiPermissionValidate(String projectKey, String userId, String gridId); | |||
| 
 | |||
|     PermissionValidateResultDTO govPermissionValidate(String projectKey, String staffId, String customerId); | |||
| } | |||
| @ -0,0 +1,193 @@ | |||
| package com.epmet.dataaggre.service.impl; | |||
| 
 | |||
| import com.epmet.commons.tools.constant.AppClientConstant; | |||
| import com.epmet.commons.tools.constant.ServiceConstant; | |||
| import com.epmet.commons.tools.dto.form.IdAndNameDTO; | |||
| import com.epmet.commons.tools.dto.result.CustomerStaffInfoCacheResult; | |||
| import com.epmet.commons.tools.exception.EpmetErrorCode; | |||
| import com.epmet.commons.tools.exception.RenException; | |||
| import com.epmet.commons.tools.feign.ResultDataResolver; | |||
| import com.epmet.commons.tools.redis.RedisKeys; | |||
| import com.epmet.commons.tools.redis.RedisUtils; | |||
| import com.epmet.commons.tools.redis.common.CustomerStaffRedis; | |||
| import com.epmet.commons.tools.utils.Result; | |||
| import com.epmet.dataaggre.dto.epmettduck.result.PermissionValidateResultDTO; | |||
| import com.epmet.dataaggre.entity.epmettduck.PrPublishRangeEntity; | |||
| import com.epmet.dataaggre.entity.epmettduck.PrUserProjectEntity; | |||
| import com.epmet.dataaggre.service.QuestionnaireService; | |||
| import com.epmet.dataaggre.service.epmettduck.PrPublishRangeService; | |||
| import com.epmet.dataaggre.service.epmettduck.PrUserProjectService; | |||
| import com.epmet.dto.CustomerGridDTO; | |||
| import com.epmet.dto.form.CustomerGridFormDTO; | |||
| import com.epmet.feign.GovOrgOpenFeignClient; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| 
 | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.UUID; | |||
| 
 | |||
| @Service | |||
| @Slf4j | |||
| public class QuestionnaireServiceImpl implements QuestionnaireService, ResultDataResolver { | |||
| 
 | |||
|     /** 调查问卷有效期  15min */ | |||
|     public static final long QUESTIONNAIRE_EXPIRE_SECONDS = 15 * 60; | |||
| 
 | |||
|     @Autowired | |||
|     private PrUserProjectService prUserProjectService; | |||
| 
 | |||
|     @Autowired | |||
|     private PrPublishRangeService prPublishRangeService; | |||
| 
 | |||
|     @Autowired | |||
|     private GovOrgOpenFeignClient govOrgOpenFeignClient; | |||
| 
 | |||
|     @Autowired | |||
|     private RedisUtils redisUtils; | |||
| 
 | |||
|     @Autowired | |||
|     private CustomerStaffRedis customerStaffRedis; | |||
| 
 | |||
|     /** | |||
|      * @description 居民端调查问卷权限校验 | |||
|      * | |||
|      * @param projectKey | |||
|      * @param userId | |||
|      * @param gridId | |||
|      * @return | |||
|      * @author wxz | |||
|      * @date 2021.09.23 17:45:25 | |||
|      */ | |||
|     public PermissionValidateResultDTO resiPermissionValidate(String projectKey, String userId, String gridId) { | |||
| 
 | |||
|         PrUserProjectEntity project = prUserProjectService.getProjectEntityBykey(projectKey); | |||
|         if (project == null || !AppClientConstant.APP_RESI.equals(project.getClient())) { | |||
|             // 工作端只能看到发布到居民端的
 | |||
|             log.warn("【调查问卷】居民端无法查看发布到工作端的调查问卷,staffId:{}, projectKey:{}", userId, projectKey); | |||
|             return generateValidateResult(userId, projectKey, false); | |||
|         } | |||
| 
 | |||
|         CustomerGridFormDTO form = new CustomerGridFormDTO(); | |||
|         form.setGridId(gridId); | |||
|         Result<CustomerGridDTO> gridInfoResult = govOrgOpenFeignClient.getGridBaseInfoByGridId(form); | |||
|         CustomerGridDTO gridInfo = getResultDataOrThrowsException(gridInfoResult, ServiceConstant.GOV_ORG_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【调查问卷】校验访问权限,查询网格信息失败"); | |||
|         // 网格父级ID列表:网格ID(拼接起来,冒号分割)
 | |||
|         String gridIdPath = gridInfo.getPids().concat(":").concat(gridInfo.getId()); | |||
|         List<PrPublishRangeEntity> publishRangeEntity = prPublishRangeService.getPublishRangeEntity(projectKey); | |||
|         PermissionValidateResultDTO r = new PermissionValidateResultDTO(); | |||
|         for (PrPublishRangeEntity rangeEntity : publishRangeEntity) { | |||
|             if (gridIdPath.contains(rangeEntity.getOrgIds())) { | |||
|                 return generateValidateResult(userId, projectKey, true); | |||
|             } | |||
|         } | |||
|         r.setPermitted(false); | |||
|         return r; | |||
|     } | |||
| 
 | |||
|     @Override | |||
|     public PermissionValidateResultDTO govPermissionValidate(String projectKey, String staffId, String customerId) { | |||
|         PrUserProjectEntity project = prUserProjectService.getProjectEntityBykey(projectKey); | |||
|         if (project == null || !"gov".equals(project.getClient())) { | |||
|             // 工作端只能看到发布到工作端的
 | |||
|             log.warn("【调查问卷】工作端无法查看发布到居民端的调查问卷,staffId:{}, projectKey:{}", staffId, projectKey); | |||
|             return generateValidateResult(staffId, projectKey, false); | |||
|         } | |||
| 
 | |||
|         List<String> gridRangeOrgIds = new ArrayList<>(); | |||
|         List<String> agencyRangeOrgIds = new ArrayList<>(); | |||
|         List<String> deptRangeOrgIds = new ArrayList<>(); | |||
| 
 | |||
|         // 将发布范围分别放到3个不同的列表中
 | |||
|         List<PrPublishRangeEntity> publishRangeEntitys = prPublishRangeService.getPublishRangeEntity(projectKey); | |||
|         publishRangeEntitys.forEach(rangeEntity -> { | |||
|             if ("grid".equals(rangeEntity.getOrgType())) { | |||
|                 gridRangeOrgIds.add(rangeEntity.getOrgIds()); | |||
|             } else if ("agency".equals(rangeEntity.getOrgType())) { | |||
|                 agencyRangeOrgIds.add(rangeEntity.getOrgIds()); | |||
|             } else if ("dept".equals(rangeEntity.getOrgType())) { | |||
|                 deptRangeOrgIds.add(rangeEntity.getOrgIds()); | |||
|             } else { | |||
|                 throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode(), String.format("【调查问卷】未知的发布范围类型:%s", rangeEntity.getOrgType())); | |||
|             } | |||
|         }); | |||
| 
 | |||
|         CustomerStaffInfoCacheResult staffInfo = customerStaffRedis.getStaffInfo(customerId, staffId); | |||
|         PermissionValidateResultDTO r = null; | |||
|         //if ("agency".equals(staffInfo.getFromOrgType())) {
 | |||
|         //    // 来自agency
 | |||
|         //
 | |||
|         //} else if ("grid".equals(staffInfo.getFromOrgType())) {
 | |||
|         //    List<IdAndNameDTO> belongGridList = staffInfo.getGridList();
 | |||
|         //
 | |||
|         //} else if ("dept".equals(staffInfo.getFromOrgType())) {
 | |||
|         //
 | |||
|         //}
 | |||
| 
 | |||
|         String agencyId = staffInfo.getAgencyId(); | |||
|         String agencyPIds = staffInfo.getAgencyPIds(); | |||
| 
 | |||
|         // 网格范围内的权限判断
 | |||
|         List<IdAndNameDTO> staffGridList = staffInfo.getGridList(); | |||
|         for (IdAndNameDTO gridIdAndName : staffGridList) { | |||
|             // 工作人员所属的 父orgId路径:网格id
 | |||
|             String staffGridIdPath = (StringUtils.isEmpty(agencyPIds) ? "" : agencyPIds.concat(":")).concat(agencyId).concat(":").concat(gridIdAndName.getId()); | |||
|             for (String gridRangeOrgId : gridRangeOrgIds) { | |||
|                 if (staffGridIdPath.contains(gridRangeOrgId)) { | |||
|                     r = generateValidateResult(staffId, projectKey, true); | |||
|                     return r; | |||
|                 } | |||
|             } | |||
|         } | |||
| 
 | |||
|         // dept范围内的权限判断
 | |||
|         List<IdAndNameDTO> staffDeptList = staffInfo.getDeptList(); | |||
|         for (IdAndNameDTO deptIdAndName : staffDeptList) { | |||
|             // 工作人员所属的 父orgId路径:网格id
 | |||
|             String staffDeptIdPath = (StringUtils.isEmpty(agencyPIds) ? "" : agencyPIds.concat(":")).concat(agencyId).concat(":").concat(deptIdAndName.getId()); | |||
|             for (String deptRangeOrgIdPath : deptRangeOrgIds) { | |||
|                 if (staffDeptIdPath.contains(deptRangeOrgIdPath)) { | |||
|                     r = generateValidateResult(staffId, projectKey, true); | |||
|                     return r; | |||
|                 } | |||
|             } | |||
|         } | |||
| 
 | |||
|         // agency范围内的权限判断
 | |||
|         String staffAgencyIdPath = (StringUtils.isEmpty(agencyPIds) ? "" : agencyPIds.concat(":")).concat(agencyId); | |||
|         for (String agencyRangeOrgId : agencyRangeOrgIds) { | |||
|             if (staffAgencyIdPath.contains(agencyRangeOrgId)) { | |||
|                 r = generateValidateResult(staffId, projectKey, true); | |||
|                 return r; | |||
|             } | |||
|         } | |||
| 
 | |||
|         // 如果上述范围中都不能判断通过,那么返回一个不通过的结果给到前端
 | |||
|         r = generateValidateResult(staffId, projectKey, false); | |||
|         return r; | |||
|     } | |||
| 
 | |||
|     /** | |||
|      * @description 生成权限允许的返回结果 | |||
|      * | |||
|      * @param userId | |||
|      * @param projectKey | |||
|      * @param permitted 是否允许访问 | |||
|      * @return | |||
|      * @author wxz | |||
|      * @date 2021.09.23 23:19:17 | |||
|      */ | |||
|     private PermissionValidateResultDTO generateValidateResult(String userId, String projectKey, Boolean permitted) { | |||
|         PermissionValidateResultDTO d = new PermissionValidateResultDTO(); | |||
|         d.setPermitted(permitted); | |||
|         if (permitted) { | |||
|             String accessKey = UUID.randomUUID().toString().replace("-", ""); | |||
|             redisUtils.set(RedisKeys.getQuestionnaireAccessKey(userId, projectKey), accessKey, QUESTIONNAIRE_EXPIRE_SECONDS); | |||
|             d.setAccessKey(accessKey); | |||
|         } | |||
|         return d; | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.datareport.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,161 @@ | |||
| package com.epmet.config; | |||
| 
 | |||
| import com.alibaba.cloud.nacos.NacosDiscoveryProperties; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.alibaba.nacos.api.naming.NamingService; | |||
| import com.alibaba.nacos.api.naming.listener.Event; | |||
| import com.alibaba.nacos.api.naming.listener.EventListener; | |||
| import com.alibaba.nacos.api.naming.listener.NamingEvent; | |||
| import com.alibaba.nacos.api.naming.pojo.ListView; | |||
| import com.epmet.commons.tools.exception.ExceptionUtils; | |||
| import com.netflix.loadbalancer.DynamicServerListLoadBalancer; | |||
| import com.netflix.loadbalancer.ILoadBalancer; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |||
| import org.springframework.cloud.netflix.ribbon.SpringClientFactory; | |||
| import org.springframework.context.annotation.Configuration; | |||
| 
 | |||
| import javax.annotation.PostConstruct; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.*; | |||
| 
 | |||
| /** | |||
|  * @author wxz | |||
|  * @Description Nacos服务列表刷新监听注册器 | |||
|  * @date 2021.09.22 14:33:11 | |||
|  */ | |||
| @Slf4j | |||
| @Configuration | |||
| @ConditionalOnProperty(prefix = "spring.cloud.nacos.discovery.serviceListChangedListening", name = "enable", havingValue = "true", matchIfMissing = false) | |||
| public class NacosServiceListListenerRegisterer { | |||
| 
 | |||
|     public static final String REFRESH_SERVER_LIST_METHOD_NAME = "restOfInit"; | |||
|     // 服务列表拉取间隔:10s
 | |||
|     public static final long SERVICE_LIST_PULLING_DELAY_SECONDS = 10; | |||
| 
 | |||
|     private NamingService namingService; | |||
| 
 | |||
|     private ScheduledExecutorService executor; | |||
| 
 | |||
|     @Autowired | |||
|     private NacosDiscoveryProperties discoveryProperties; | |||
| 
 | |||
|     @Autowired | |||
|     private SpringClientFactory springClientFactory; | |||
| 
 | |||
|     // 监听中的服务列表
 | |||
|     private List<String> observingServers = new ArrayList<>(33); | |||
| 
 | |||
|     @PostConstruct | |||
|     public void init() { | |||
|         namingService = discoveryProperties.namingServiceInstance(); | |||
|         // 启动监听
 | |||
|         executor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() { | |||
|             @Override | |||
|             public Thread newThread(Runnable r) { | |||
|                 Thread thread = new Thread(r); | |||
|                 thread.setDaemon(true); | |||
|                 thread.setName("NacosServiceListWatchingRegisterer"); | |||
|                 return thread; | |||
|             } | |||
|         }); | |||
| 
 | |||
|         // 立即启动,并15s刷新一次服务列表,用于新服务列表的发现
 | |||
|         ScheduledFuture<?> future = executor.scheduleAtFixedRate(new EpmetNacosServiceListListener(), 0, SERVICE_LIST_PULLING_DELAY_SECONDS, TimeUnit.SECONDS); | |||
|     } | |||
| 
 | |||
|     public class EpmetNacosServiceListListener implements Runnable { | |||
| 
 | |||
|         @Override | |||
|         public void run() { | |||
|             doRefreshServerList(); | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param | |||
|          * @return | |||
|          * @description 执行刷新 | |||
|          * @author wxz | |||
|          * @date 2021.09.22 16:04:49 | |||
|          */ | |||
|         private synchronized void doRefreshServerList() { | |||
|             ListView<String> serviceListView = null; | |||
|             try { | |||
|                 serviceListView = namingService.getServicesOfServer(1, 100); | |||
|                 //启动监听
 | |||
|                 if (serviceListView == null || serviceListView.getCount() == 0) { | |||
|                     log.info("【Nacos服务列表定时刷新】当前无任何可添加监听的服务"); | |||
|                     return; | |||
|                 } | |||
|                 List<String> serviceList = serviceListView.getData(); | |||
|                 log.info("【Nacos服务列表定时刷新】Nacos服务端服务列表: {}", serviceList); | |||
| 
 | |||
|                 for (String service : serviceList) { | |||
|                     try { | |||
| 
 | |||
|                         // 如果该服务已经在监听列表中存在了,则不再注册监听。注:不能取消空服务的监听,因为空服务随时可能恢复运行,需要实时监听。
 | |||
|                         if (observingServers.contains(service)) { | |||
|                             continue; | |||
|                         } | |||
| 
 | |||
|                         namingService.subscribe(service, new EventListener() { | |||
|                             @Override | |||
|                             public void onEvent(Event event) { | |||
|                                 if (event instanceof NamingEvent) { | |||
|                                     NamingEvent namingEvent = (NamingEvent) event; | |||
|                                     log.info("【Nacos服务列表刷新监听】收到事件:{}:[{}]", namingEvent.getServiceName(), namingEvent.getInstances()); | |||
|                                     doRefreshServerList(service); | |||
|                                 } | |||
|                             } | |||
|                         }); | |||
| 
 | |||
|                         // 将该服务加入到监听列表中
 | |||
|                         observingServers.add(service); | |||
|                     } catch (NacosException e) { | |||
|                         String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                         log.error("【Nacos服务列表定时刷新】订阅ApplicationContext的刷新事件失败,错误信息:{}", errorStackTrace); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } catch (NacosException e) { | |||
|                 String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); | |||
|                 log.error("【Nacos服务列表定时刷新】链接Nacos服务端失败,错误信息:{}", errorStackTrace); | |||
|             } | |||
|         } | |||
| 
 | |||
|         /** | |||
|          * @param serviceName | |||
|          * @return | |||
|          * @description 刷新ServerList | |||
|          * @author wxz | |||
|          * @date 2021.09.22 09:29:16 | |||
|          */ | |||
|         private void doRefreshServerList(String serviceName) { | |||
|             // 刷新方式1:反射调用DynamicServerListLoadBalancer中的restOfInit()方法。该方法原来只执行一次,此处不推荐用
 | |||
|             //ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName);
 | |||
|             //if (loadBalancer instanceof ZoneAwareLoadBalancer) {
 | |||
|             //    ZoneAwareLoadBalancer zaLoadBalancer = (ZoneAwareLoadBalancer) loadBalancer;
 | |||
|             //    IClientConfig clientConfig = springClientFactory.getClientConfig(serviceName);
 | |||
|             //    try {
 | |||
|             //        Method restOfInitMethod = zaLoadBalancer.getClass().getSuperclass().getDeclaredMethod(REFRESH_SERVER_LIST_METHOD_NAME, IClientConfig.class);
 | |||
|             //        restOfInitMethod.setAccessible(true);
 | |||
|             //        restOfInitMethod.invoke(zaLoadBalancer, clientConfig);
 | |||
|             //    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
 | |||
|             //        String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
 | |||
|             //        log.error("【LoadBalancer刷新服务列表】失败:{}", errorStackTrace);
 | |||
|             //    }
 | |||
|             //}
 | |||
| 
 | |||
|             // 刷新方式2:DynamicServerListLoadBalancer#updateListOfServers()该方法为ribbon定时刷新服务列表的时候真正调用的方法,但是加了@VisibleForTesting
 | |||
|             //      暂且 1 try
 | |||
|             ILoadBalancer loadBalancer = springClientFactory.getLoadBalancer(serviceName); | |||
|             if (loadBalancer instanceof DynamicServerListLoadBalancer) { | |||
|                 DynamicServerListLoadBalancer dslb = (DynamicServerListLoadBalancer) loadBalancer; | |||
|                 dslb.updateListOfServers(); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
Some files were not shown because too many files changed in this diff
					Loading…
					
					
				
		Reference in new issue