jianjun 4 years ago
parent
commit
d9f3db112f
  1. 10
      epmet-admin/epmet-admin-server/pom.xml
  2. 161
      epmet-admin/epmet-admin-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  3. 2
      epmet-admin/epmet-admin-server/src/main/resources/bootstrap.yml
  4. 9
      epmet-auth/pom.xml
  5. 161
      epmet-auth/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  6. 13
      epmet-gateway/pom.xml
  7. 161
      epmet-gateway/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  8. 3
      epmet-gateway/src/main/resources/bootstrap.yml
  9. 9
      epmet-module/data-aggregator/data-aggregator-server/pom.xml
  10. 161
      epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/config/NacosServiceListListenerRegisterer.java
  11. 2
      epmet-module/data-aggregator/data-aggregator-server/src/main/resources/bootstrap.yml
  12. 9
      epmet-module/data-report/data-report-server/pom.xml
  13. 161
      epmet-module/data-report/data-report-server/src/main/java/com/epmet/datareport/config/NacosServiceListListenerRegisterer.java
  14. 2
      epmet-module/data-report/data-report-server/src/main/resources/bootstrap.yml
  15. 8
      epmet-module/data-statistical/data-statistical-server/pom.xml
  16. 161
      epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  17. 2
      epmet-module/data-statistical/data-statistical-server/src/main/resources/bootstrap.yml
  18. 8
      epmet-module/epmet-activiti/epmet-activiti-server/pom.xml
  19. 2
      epmet-module/epmet-activiti/epmet-activiti-server/src/main/resources/bootstrap.yml
  20. 8
      epmet-module/epmet-common-service/common-service-server/pom.xml
  21. 161
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  22. 2
      epmet-module/epmet-common-service/common-service-server/src/main/resources/bootstrap.yml
  23. 7
      epmet-module/epmet-demo/epmet-demo-server/pom.xml
  24. 161
      epmet-module/epmet-demo/epmet-demo-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  25. 2
      epmet-module/epmet-demo/epmet-demo-server/src/main/resources/bootstrap.yml
  26. 8
      epmet-module/epmet-ext/epmet-ext-server/pom.xml
  27. 161
      epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  28. 2
      epmet-module/epmet-ext/epmet-ext-server/src/main/resources/bootstrap.yml
  29. 8
      epmet-module/epmet-heart/epmet-heart-server/pom.xml
  30. 161
      epmet-module/epmet-heart/epmet-heart-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  31. 2
      epmet-module/epmet-heart/epmet-heart-server/src/main/resources/bootstrap.yml
  32. 9
      epmet-module/epmet-job/epmet-job-server/pom.xml
  33. 161
      epmet-module/epmet-job/epmet-job-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  34. 2
      epmet-module/epmet-job/epmet-job-server/src/main/resources/bootstrap.yml
  35. 9
      epmet-module/epmet-message/epmet-message-server/pom.xml
  36. 161
      epmet-module/epmet-message/epmet-message-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  37. 2
      epmet-module/epmet-message/epmet-message-server/src/main/resources/bootstrap.yml
  38. 8
      epmet-module/epmet-oss/epmet-oss-server/pom.xml
  39. 161
      epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  40. 2
      epmet-module/epmet-oss/epmet-oss-server/src/main/resources/bootstrap.yml
  41. 8
      epmet-module/epmet-point/epmet-point-server/pom.xml
  42. 161
      epmet-module/epmet-point/epmet-point-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  43. 4
      epmet-module/epmet-point/epmet-point-server/src/main/resources/bootstrap.yml
  44. 8
      epmet-module/epmet-third/epmet-third-server/pom.xml
  45. 161
      epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  46. 2
      epmet-module/epmet-third/epmet-third-server/src/main/resources/bootstrap.yml
  47. 8
      epmet-module/gov-access/gov-access-server/pom.xml
  48. 161
      epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  49. 2
      epmet-module/gov-access/gov-access-server/src/main/resources/bootstrap.yml
  50. 8
      epmet-module/gov-grid/gov-grid-server/pom.xml
  51. 161
      epmet-module/gov-grid/gov-grid-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  52. 2
      epmet-module/gov-grid/gov-grid-server/src/main/resources/bootstrap.yml
  53. 8
      epmet-module/gov-issue/gov-issue-server/pom.xml
  54. 161
      epmet-module/gov-issue/gov-issue-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  55. 2
      epmet-module/gov-issue/gov-issue-server/src/main/resources/bootstrap.yml
  56. 11
      epmet-module/gov-mine/gov-mine-server/pom.xml
  57. 161
      epmet-module/gov-mine/gov-mine-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  58. 2
      epmet-module/gov-mine/gov-mine-server/src/main/resources/bootstrap.yml
  59. 8
      epmet-module/gov-org/gov-org-server/pom.xml
  60. 161
      epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  61. 3
      epmet-module/gov-org/gov-org-server/src/main/resources/bootstrap.yml
  62. 8
      epmet-module/gov-project/gov-project-server/pom.xml
  63. 161
      epmet-module/gov-project/gov-project-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  64. 2
      epmet-module/gov-project/gov-project-server/src/main/resources/bootstrap.yml
  65. 8
      epmet-module/gov-voice/gov-voice-server/pom.xml
  66. 161
      epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  67. 2
      epmet-module/gov-voice/gov-voice-server/src/main/resources/bootstrap.yml
  68. 8
      epmet-module/oper-access/oper-access-server/pom.xml
  69. 161
      epmet-module/oper-access/oper-access-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  70. 2
      epmet-module/oper-access/oper-access-server/src/main/resources/bootstrap.yml
  71. 8
      epmet-module/oper-crm/oper-crm-server/pom.xml
  72. 161
      epmet-module/oper-crm/oper-crm-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  73. 2
      epmet-module/oper-crm/oper-crm-server/src/main/resources/bootstrap.yml
  74. 8
      epmet-module/oper-customize/oper-customize-server/pom.xml
  75. 161
      epmet-module/oper-customize/oper-customize-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  76. 2
      epmet-module/oper-customize/oper-customize-server/src/main/resources/bootstrap.yml
  77. 11
      epmet-module/resi-group/resi-group-server/pom.xml
  78. 161
      epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  79. 2
      epmet-module/resi-group/resi-group-server/src/main/resources/bootstrap.yml
  80. 9
      epmet-module/resi-guide/resi-guide-server/pom.xml
  81. 161
      epmet-module/resi-guide/resi-guide-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  82. 2
      epmet-module/resi-guide/resi-guide-server/src/main/resources/bootstrap.yml
  83. 8
      epmet-module/resi-hall/resi-hall-server/pom.xml
  84. 161
      epmet-module/resi-hall/resi-hall-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  85. 2
      epmet-module/resi-hall/resi-hall-server/src/main/resources/bootstrap.yml
  86. 13
      epmet-module/resi-home/resi-home-server/pom.xml
  87. 161
      epmet-module/resi-home/resi-home-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  88. 2
      epmet-module/resi-home/resi-home-server/src/main/resources/bootstrap.yml
  89. 13
      epmet-module/resi-mine/resi-mine-server/pom.xml
  90. 161
      epmet-module/resi-mine/resi-mine-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  91. 2
      epmet-module/resi-mine/resi-mine-server/src/main/resources/bootstrap.yml
  92. 9
      epmet-module/resi-partymember/resi-partymember-server/pom.xml
  93. 161
      epmet-module/resi-partymember/resi-partymember-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  94. 2
      epmet-module/resi-partymember/resi-partymember-server/src/main/resources/bootstrap.yml
  95. 10
      epmet-module/resi-voice/resi-voice-server/pom.xml
  96. 161
      epmet-module/resi-voice/resi-voice-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java
  97. 2
      epmet-module/resi-voice/resi-voice-server/src/main/resources/bootstrap.yml
  98. 15
      epmet-openapi/epmet-openapi-scan/pom.xml
  99. 161
      epmet-openapi/epmet-openapi-scan/src/main/java/com/epmet/openapi/scan/config/NacosServiceListListenerRegisterer.java
  100. 2
      epmet-openapi/epmet-openapi-scan/src/main/resources/bootstrap.yml

10
epmet-admin/epmet-admin-server/pom.xml

@ -132,6 +132,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -170,6 +172,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--rocketmq-->
@ -203,6 +208,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -238,6 +245,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--rocketmq-->

161
epmet-admin/epmet-admin-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-admin/epmet-admin-server/src/main/resources/bootstrap.yml

@ -61,6 +61,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

9
epmet-auth/pom.xml

@ -183,6 +183,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--公众号配置-->
<wx.mp.configs.appId>wxcb6ce2ed0c5ae54c</wx.mp.configs.appId>
@ -238,6 +240,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--公众号配置-->
<wx.mp.configs.appId>wxcb6ce2ed0c5ae54c</wx.mp.configs.appId>
@ -290,6 +294,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--公众号配置-->
<wx.mp.configs.appId>wxcb6ce2ed0c5ae54c</wx.mp.configs.appId>
@ -345,6 +351,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--公众号配置-->
<wx.mp.configs.appId>wxcb6ce2ed0c5ae54c</wx.mp.configs.appId>
<wx.mp.configs.secret>c7f74941ee97fa9b2e1065772d34c397</wx.mp.configs.secret>

161
epmet-auth/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

13
epmet-gateway/pom.xml

@ -124,6 +124,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip></nacos.ip>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!-- gateway routes -->
<!-- 1、认证服务 -->
<!-- <gateway.routes.epmet-auth-server.uri>http://localhost:8081</gateway.routes.epmet-auth-server.uri>-->
@ -255,6 +258,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip></nacos.ip>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!-- gateway routes -->
<!-- 1、认证服务 -->
<!-- <gateway.routes.epmet-auth-server.uri>http://localhost:8081</gateway.routes.epmet-auth-server.uri>-->
@ -389,6 +395,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!-- gateway routes -->
<!-- 1、认证服务 -->
<gateway.routes.epmet-auth-server.uri>lb://epmet-auth-server</gateway.routes.epmet-auth-server.uri>
@ -488,6 +497,10 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!-- gateway routes -->
<!-- 1、认证服务 -->
<gateway.routes.epmet-auth-server.uri>lb://epmet-auth-server</gateway.routes.epmet-auth-server.uri>

161
epmet-gateway/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

3
epmet-gateway/src/main/resources/bootstrap.yml

@ -358,6 +358,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@
@ -427,6 +429,7 @@ feign:
config:
default:
loggerLevel: BASIC
readTimeout: 600000
okhttp:
enabled: true

9
epmet-module/data-aggregator/data-aggregator-server/pom.xml

@ -222,6 +222,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -336,6 +338,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -450,6 +454,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -565,6 +571,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/data-aggregator/data-aggregator-server/src/main/resources/bootstrap.yml

@ -37,6 +37,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

9
epmet-module/data-report/data-report-server/pom.xml

@ -167,6 +167,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -219,6 +221,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -271,6 +275,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -323,6 +329,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/data-report/data-report-server/src/main/java/com/epmet/datareport/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/data-report/data-report-server/src/main/resources/bootstrap.yml

@ -37,6 +37,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/data-statistical/data-statistical-server/pom.xml

@ -241,6 +241,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -361,6 +363,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -481,6 +485,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -597,6 +603,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>

161
epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/data-statistical/data-statistical-server/src/main/resources/bootstrap.yml

@ -37,6 +37,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/epmet-activiti/epmet-activiti-server/pom.xml

@ -181,6 +181,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
</properties>
@ -213,6 +215,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
</properties>
@ -242,6 +246,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
</properties>
@ -271,6 +277,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
</properties>

2
epmet-module/epmet-activiti/epmet-activiti-server/src/main/resources/bootstrap.yml

@ -50,6 +50,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/epmet-common-service/common-service-server/pom.xml

@ -123,6 +123,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--亿联云消息网关配置-->
@ -169,6 +171,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--亿联云消息网关配置-->
@ -213,6 +217,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--亿联云消息网关配置-->
@ -254,6 +260,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--亿联云消息网关配置-->

161
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-common-service/common-service-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

7
epmet-module/epmet-demo/epmet-demo-server/pom.xml

@ -127,6 +127,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
</properties>
</profile>
<profile>
@ -136,7 +138,7 @@
</activation>-->
<properties>
<server.port>8088</server.port>
<spring.profiles.active>dev</spring.profiles.active>
<spring.profiles.active>test</spring.profiles.active>
<!-- 数据库配置-->
<spring.datasource.druid.url>
@ -157,6 +159,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
</properties>
</profile>
</profiles>

161
epmet-module/epmet-demo/epmet-demo-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-demo/epmet-demo-server/src/main/resources/bootstrap.yml

@ -40,6 +40,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/epmet-ext/epmet-ext-server/pom.xml

@ -215,6 +215,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -254,6 +256,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -293,6 +297,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -333,6 +339,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-ext/epmet-ext-server/src/main/resources/bootstrap.yml

@ -35,6 +35,8 @@ spring:
namespace: @nacos.discovery.namespace@
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/epmet-heart/epmet-heart-server/pom.xml

@ -133,6 +133,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -174,6 +176,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -215,6 +219,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -256,6 +262,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-open.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>

161
epmet-module/epmet-heart/epmet-heart-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-heart/epmet-heart-server/src/main/resources/bootstrap.yml

@ -37,6 +37,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

9
epmet-module/epmet-job/epmet-job-server/pom.xml

@ -136,6 +136,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -171,6 +173,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -206,6 +210,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -239,6 +245,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--生产钉钉 机器人地址-->

161
epmet-module/epmet-job/epmet-job-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-job/epmet-job-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

9
epmet-module/epmet-message/epmet-message-server/pom.xml

@ -182,6 +182,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -231,6 +233,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -279,6 +283,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -325,6 +331,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--线程池配置-->

161
epmet-module/epmet-message/epmet-message-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-message/epmet-message-server/src/main/resources/bootstrap.yml

@ -40,6 +40,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/epmet-oss/epmet-oss-server/pom.xml

@ -141,6 +141,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -180,6 +182,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -218,6 +222,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -253,6 +259,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--生产钉钉 机器人地址-->

161
epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-oss/epmet-oss-server/src/main/resources/bootstrap.yml

@ -54,6 +54,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/epmet-point/epmet-point-server/pom.xml

@ -154,6 +154,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -195,6 +197,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -236,6 +240,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -277,6 +283,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/epmet-point/epmet-point-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

4
epmet-module/epmet-point/epmet-point-server/src/main/resources/bootstrap.yml

@ -37,6 +37,9 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
# 是否开启服务实例列表变更监听
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@
@ -113,6 +116,7 @@ hystrix:
ribbon:
ReadTimeout: 300000
ConnectTimeout: 300000
# ServerListRefreshInterval: 5000
#pageHelper分页插件
pagehelper:

8
epmet-module/epmet-third/epmet-third-server/pom.xml

@ -197,6 +197,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -236,6 +238,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -274,6 +278,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -313,6 +319,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/epmet-third/epmet-third-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/epmet-third/epmet-third-server/src/main/resources/bootstrap.yml

@ -35,6 +35,8 @@ spring:
namespace: @nacos.discovery.namespace@
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/gov-access/gov-access-server/pom.xml

@ -124,6 +124,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -161,6 +163,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -198,6 +202,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -232,6 +238,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--flyway migration 数据库迁移工具-->
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/gov-access/gov-access-server/src/main/resources/bootstrap.yml

@ -37,6 +37,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/gov-grid/gov-grid-server/pom.xml

@ -116,6 +116,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -148,6 +150,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -180,6 +184,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -212,6 +218,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/gov-grid/gov-grid-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/gov-grid/gov-grid-server/src/main/resources/bootstrap.yml

@ -33,6 +33,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/gov-issue/gov-issue-server/pom.xml

@ -166,6 +166,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -207,6 +209,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -248,6 +252,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -285,6 +291,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-open.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>

161
epmet-module/gov-issue/gov-issue-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/gov-issue/gov-issue-server/src/main/resources/bootstrap.yml

@ -37,6 +37,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

11
epmet-module/gov-mine/gov-mine-server/pom.xml

@ -136,6 +136,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -166,6 +169,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -196,6 +202,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--测试钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -223,6 +232,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--生产钉钉 机器人地址-->
<dingTalk.robot.webHook>

161
epmet-module/gov-mine/gov-mine-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/gov-mine/gov-mine-server/src/main/resources/bootstrap.yml

@ -30,6 +30,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/gov-org/gov-org-server/pom.xml

@ -160,6 +160,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -203,6 +205,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -246,6 +250,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -287,6 +293,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

3
epmet-module/gov-org/gov-org-server/src/main/resources/bootstrap.yml

@ -70,6 +70,9 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
# 是否开启服务实例列表变更监听
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/gov-project/gov-project-server/pom.xml

@ -165,6 +165,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -205,6 +207,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -244,6 +248,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -280,6 +286,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-open.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>

161
epmet-module/gov-project/gov-project-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/gov-project/gov-project-server/src/main/resources/bootstrap.yml

@ -46,6 +46,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/gov-voice/gov-voice-server/pom.xml

@ -129,6 +129,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -168,6 +170,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -207,6 +211,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-dev.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>
@ -243,6 +249,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<openapi.scan.server.url>https://epmet-open.elinkservice.cn/api/epmetscan/api</openapi.scan.server.url>

161
epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/gov-voice/gov-voice-server/src/main/resources/bootstrap.yml

@ -46,6 +46,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/oper-access/oper-access-server/pom.xml

@ -117,6 +117,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -155,6 +157,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -193,6 +197,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -228,6 +234,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/oper-access/oper-access-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/oper-access/oper-access-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/oper-crm/oper-crm-server/pom.xml

@ -162,6 +162,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -200,6 +202,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -238,6 +242,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -276,6 +282,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/oper-crm/oper-crm-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/oper-crm/oper-crm-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/oper-customize/oper-customize-server/pom.xml

@ -134,6 +134,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -177,6 +179,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -220,6 +224,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -260,6 +266,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/oper-customize/oper-customize-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/oper-customize/oper-customize-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

11
epmet-module/resi-group/resi-group-server/pom.xml

@ -181,6 +181,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -238,6 +240,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -293,6 +297,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--亿联云消息网关配置-->
@ -345,6 +352,10 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--亿联云消息网关配置-->

161
epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-group/resi-group-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

9
epmet-module/resi-guide/resi-guide-server/pom.xml

@ -138,6 +138,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -176,6 +178,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -214,6 +218,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -250,6 +256,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--生产钉钉 机器人地址-->

161
epmet-module/resi-guide/resi-guide-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-guide/resi-guide-server/src/main/resources/bootstrap.yml

@ -50,6 +50,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

8
epmet-module/resi-hall/resi-hall-server/pom.xml

@ -102,6 +102,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -134,6 +136,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
<!--钉钉 机器人地址-->
@ -166,6 +170,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
<!--测试钉钉 机器人地址-->
@ -195,6 +201,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/resi-hall/resi-hall-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-hall/resi-hall-server/src/main/resources/bootstrap.yml

@ -33,6 +33,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

13
epmet-module/resi-home/resi-home-server/pom.xml

@ -126,6 +126,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -156,6 +159,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -186,6 +192,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--测试钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -213,6 +222,10 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--生产钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=a5f66c3374b1642fe2142dbf56d5997e280172d4e8f2b546c9423a68c82ece6c

161
epmet-module/resi-home/resi-home-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-home/resi-home-server/src/main/resources/bootstrap.yml

@ -33,6 +33,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

13
epmet-module/resi-mine/resi-mine-server/pom.xml

@ -145,6 +145,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -174,6 +177,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -203,6 +209,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--测试钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -229,6 +238,10 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--生产钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=a5f66c3374b1642fe2142dbf56d5997e280172d4e8f2b546c9423a68c82ece6c

161
epmet-module/resi-mine/resi-mine-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-mine/resi-mine-server/src/main/resources/bootstrap.yml

@ -33,6 +33,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

9
epmet-module/resi-partymember/resi-partymember-server/pom.xml

@ -144,6 +144,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -183,6 +185,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>false</spring.flyway.enabled>
@ -222,6 +226,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>
@ -259,6 +265,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<spring.flyway.enabled>true</spring.flyway.enabled>

161
epmet-module/resi-partymember/resi-partymember-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-partymember/resi-partymember-server/src/main/resources/bootstrap.yml

@ -49,6 +49,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

10
epmet-module/resi-voice/resi-voice-server/pom.xml

@ -102,6 +102,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
@ -133,6 +136,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
@ -164,6 +169,8 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--测试钉钉 机器人地址-->
<dingTalk.robot.webHook>
@ -196,6 +203,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--生产钉钉 机器人地址-->
<dingTalk.robot.webHook>

161
epmet-module/resi-voice/resi-voice-server/src/main/java/com/epmet/config/NacosServiceListListenerRegisterer.java

@ -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();
}
}
}
}

2
epmet-module/resi-voice/resi-voice-server/src/main/resources/bootstrap.yml

@ -30,6 +30,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

15
epmet-openapi/epmet-openapi-scan/pom.xml

@ -104,6 +104,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -119,7 +122,7 @@
</activation>
<properties>
<server.port>8107</server.port>
<spring.profiles.active>dev</spring.profiles.active>
<spring.profiles.active>local</spring.profiles.active>
<!-- redis配置 -->
@ -135,6 +138,10 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -162,6 +169,9 @@
<nacos.config.group></nacos.config.group>
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>true</nacos.service-list-changed-listening.enable>
<!--测试钉钉 机器人地址-->
<dingTalk.robot.webHook>
https://oapi.dingtalk.com/robot/send?access_token=e894e5690f9d6a527722974c71548ff6c0fe29bd956589a09e21b16442a35ed4
@ -194,6 +204,9 @@
<nacos.config-enabled>false</nacos.config-enabled>
<nacos.ip/>
<!--是否开启服务列表变更监听-->
<nacos.service-list-changed-listening.enable>false</nacos.service-list-changed-listening.enable>
<!--生产钉钉 机器人地址-->
<dingTalk.robot.webHook>

161
epmet-openapi/epmet-openapi-scan/src/main/java/com/epmet/openapi/scan/config/NacosServiceListListenerRegisterer.java

@ -0,0 +1,161 @@
package com.epmet.openapi.scan.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();
}
}
}
}

2
epmet-openapi/epmet-openapi-scan/src/main/resources/bootstrap.yml

@ -33,6 +33,8 @@ spring:
#不把自己注册到注册中心的地址
register-enabled: @nacos.register-enabled@
ip: @nacos.ip@
serviceListChangedListening:
enable: @nacos.service-list-changed-listening.enable@
config:
enabled: @nacos.config-enabled@
server-addr: @nacos.server-addr@

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save