优化eureka服务发现

eureka
tanghc 5 years ago
parent 8d63d865f6
commit 4ab47a5be2
  1. 13
      sop-admin/sop-admin-server/src/main/resources/application-dev.properties
  2. 76
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRegistryListener.java
  3. 8
      sop-example/sop-book/sop-book-web/pom.xml
  4. 5
      sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties
  5. 8
      sop-example/sop-story/sop-story-web/pom.xml
  6. 4
      sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties
  7. 8
      sop-gateway/pom.xml
  8. 7
      sop-gateway/src/main/resources/application-dev.properties

@ -17,8 +17,17 @@ admin.access-token.timeout-minutes=30
sop.sign-type=rsa
# nacos配置
nacos.config.server-addr=${nacos.url}
nacos.discovery.server-addr=${nacos.url}
#nacos.config.server-addr=${nacos.url}
#nacos.discovery.server-addr=${nacos.url}
# 网关地址,多个用逗号隔开
# 在不使用nacos时有用,使用nacos时注释掉
gateway.host=127.0.0.1:8081
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# 如果使用eureka,填eureka,使用nacos,填eureka
registry.name=eureka
# 数据库配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

@ -2,10 +2,13 @@ package com.gitee.sop.gatewaycommon.route;
import com.gitee.sop.gatewaycommon.bean.InstanceDefinition;
import com.gitee.sop.gatewaycommon.loadbalancer.EurekaEnvironmentServerChooser;
import com.gitee.sop.gatewaycommon.loadbalancer.SopPropertiesFactory;
import com.gitee.sop.gatewaycommon.manager.EnvironmentKeys;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.context.ApplicationEvent;
@ -27,50 +30,77 @@ public class EurekaRegistryListener extends BaseRegistryListener {
System.setProperty(EnvironmentKeys.ZUUL_CUSTOM_RULE_CLASSNAME.getKey(), EurekaEnvironmentServerChooser.class.getName());
}
private Set<String> cacheServices = new HashSet<>();
private Set<ServiceHolder> cacheServices = new HashSet<>();
/**
* 注册中心触发事件可以从中获取服务<br>
*
* 这个方法做的事情有2个<br>
*
* 1. 找出新注册的服务调用pullRoutes方法<br>
* 2. 找出删除的服务调用removeRoutes方法<br>
*
* @param applicationEvent 事件体
*/
@Override
public void onEvent(ApplicationEvent applicationEvent) {
Object source = applicationEvent.getSource();
CloudEurekaClient cloudEurekaClient = (CloudEurekaClient) source;
Applications applications = cloudEurekaClient.getApplications();
List<Application> registeredApplications = applications.getRegisteredApplications();
List<String> serviceList = registeredApplications
List<ServiceHolder> serviceList = registeredApplications
.stream()
.map(Application::getName)
.filter(application -> CollectionUtils.isNotEmpty(application.getInstances()))
.map(Application::getInstances)
.map(instanceInfos -> {
// 根据更新时间倒叙
instanceInfos.sort(Comparator.comparing(InstanceInfo::getLastUpdatedTimestamp).reversed());
// 获取最新的个服务实例,说明这个服务实例刚刚重启过
return instanceInfos.get(0);
})
.map(instanceInfo -> new ServiceHolder(instanceInfo.getAppName(), instanceInfo.getLastUpdatedTimestamp()))
.collect(Collectors.toList());
final Set<String> currentServices = new HashSet<>(serviceList);
final Set<ServiceHolder> currentServices = new HashSet<>(serviceList);
currentServices.removeAll(cacheServices);
// 如果有新的服务注册进来
if (currentServices.size() > 0) {
List<Application> newApplications = registeredApplications.stream()
.filter(application -> this.canOperator(application.getName())
&& currentServices.contains(application.getName()))
.filter(application ->
this.canOperator(application.getName()) && containsService(currentServices, application.getName()))
.collect(Collectors.toList());
this.doRegister(newApplications);
}
cacheServices.removeAll(new HashSet<>(serviceList));
Set<String> removedServiceIdList = getRemovedServiceId(serviceList);
// 如果有服务删除
if (cacheServices.size() > 0) {
this.doRemove(cacheServices);
if (removedServiceIdList.size() > 0) {
this.doRemove(removedServiceIdList);
}
// 缓存最新服务
cacheServices = new HashSet<>(serviceList);
}
/**
* 获取已经下线的serviceId
*
* @param serviceList 最新的serviceId集合
* @return 返回已下线的serviceId
*/
private Set<String> getRemovedServiceId(List<ServiceHolder> serviceList) {
Set<String> cache = cacheServices.stream()
.map(ServiceHolder::getServiceId)
.collect(Collectors.toSet());
Set<String> newList = serviceList.stream()
.map(ServiceHolder::getServiceId)
.collect(Collectors.toSet());
cache.removeAll(newList);
return cache;
}
private static boolean containsService(Set<ServiceHolder> currentServices, String serviceId) {
for (ServiceHolder currentService : currentServices) {
if (currentService.getServiceId().equalsIgnoreCase(serviceId)) {
return true;
}
}
return false;
}
private void doRegister(List<Application> registeredApplications) {
registeredApplications.forEach(application -> {
List<InstanceInfo> instances = application.getInstances();
@ -92,4 +122,10 @@ public class EurekaRegistryListener extends BaseRegistryListener {
deletedServices.forEach(this::removeRoutes);
}
@Data
@AllArgsConstructor
private static class ServiceHolder {
private String serviceId;
private long lastUpdatedTimestamp;
}
}

@ -45,7 +45,7 @@
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
@ -56,8 +56,14 @@
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
-->
<!-- 注册中心end -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>

@ -2,7 +2,10 @@ server.port=3333
spring.application.name=book-service
# nacos注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# consumer不需要检查provider是否启动
dubbo.consumer.check=false

@ -39,7 +39,7 @@
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
@ -50,8 +50,14 @@
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
-->
<!-- 注册中心end -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>

@ -4,8 +4,10 @@ spring.application.name=story-service
# 如果有context-path,必须配下面这句
#spring.cloud.nacos.discovery.metadata.server.servlet.context-path=${server.servlet.context-path}
# nacos注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# dubbo配置
dubbo.protocol.name=dubbo

@ -57,7 +57,7 @@
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
@ -68,8 +68,14 @@
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
-->
<!-- 注册中心end -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--
这里依赖springboot版本,非cloud版本。
如果依赖了spring-cloud-starter-alibaba-nacos-config,需要额外配置一个bootstrap.properties

@ -37,8 +37,11 @@ ribbon.ReadTimeout=2000
ribbon.OkToRetryOnAllOperations=false
# nacos cloud配置
spring.cloud.nacos.discovery.server-addr=${nacos.url}
nacos.config.server-addr=${nacos.url}
#spring.cloud.nacos.discovery.server-addr=${nacos.url}
#nacos.config.server-addr=${nacos.url}
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://${mysql.host}/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai

Loading…
Cancel
Save