Eureka【支持Remote Region】
工程公共pom依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
1、eureka server工程
1.1、eureka server工程pom依赖:
<!--加上文章头部的公共依赖-->
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
1.2、项目启动类:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurkeaServerApplication { public static void main(String[] args) { SpringApplication.run(EurkeaServerApplication.class, args); } }
1.3、这里配置4个eureka server实例,路径:eureka-server\src\main\resources\,分4个zone,属于region-east、region-west两个区。
属于region-east的配置文件为:application-zone1.yml,application-zone2.yml
application-zone1.yml:
server: port: 8761 spring: application: name: eureka-server eureka: server: waitTimeInMsWhenSyncEmpty: 0 enableSelfPreservation: false remoteRegionUrlsWithName: region-west: http://localhost:8763/eureka/ client: register-with-eureka: true fetch-registry: true region: region-east service-url: zone1: http://localhost:8761/eureka/ zone2: http://localhost:8762/eureka/ availability-zones: region-east: zone1,zone2 instance: hostname: localhost metadataMap.zone: zone1
application-zone2.yml:
server: port: 8762 spring: application: name: eureka-server eureka: server: waitTimeInMsWhenSyncEmpty: 0 enableSelfPreservation: false remoteRegionUrlsWithName: region-west: http://localhost:8763/eureka/ client: register-with-eureka: true fetch-registry: true region: region-east service-url: zone1: http://localhost:8761/eureka/ zone2: http://localhost:8762/eureka/ availability-zones: region-east: zone1,zone2 instance: hostname: localhost metadataMap.zone: zone2
属于region-west的配置文件为:application-zone3-region-west.yml,application-zone4-region-west.yml
application-zone3-region-west.yml
server: port: 8763 spring: application: name: eureka-server eureka: server: waitTimeInMsWhenSyncEmpty: 0 enableSelfPreservation: false remoteRegionUrlsWithName: region-east: http://localhost:8761/eureka/ client: register-with-eureka: true fetch-registry: true region: region-west service-url: zone3: http://localhost:8763/eureka/ zone4: http://localhost:8764/eureka/ availability-zones: region-west: zone3,zone4 instance: hostname: localhost metadataMap.zone: zone3
application-zone4-region-west.yml
server: port: 8764 spring: application: name: eureka-server eureka: server: waitTimeInMsWhenSyncEmpty: 0 enableSelfPreservation: false remoteRegionUrlsWithName: region-east: http://localhost:8761/eureka/ client: register-with-eureka: true fetch-registry: true region: region-west service-url: zone3: http://localhost:8763/eureka/ zone4: http://localhost:8764/eureka/ availability-zones: region-west: zone3,zone4 instance: hostname: localhost metadataMap.zone: zone4
由于框架中,EurekaServerConfigBean的remoteRegionAppWhitelist默认值是null,而getRemoteRegionAppWhitelist(String regionName)方法又被直接调用,如果工程上不处理,就直接空指针异常了。
//框架源码
package org.springframework.cloud.netflix.eureka.server; import ...... @ConfigurationProperties("eureka.server") public class EurekaServerConfigBean implements EurekaServerConfig { public static final String PREFIX = "eureka.server"; private static final int MINUTES = 60000; @Autowired( required = false ) PropertyResolver propertyResolver; private String aWSAccessId; //.....private String[] remoteRegionUrls; private Map<String, Set<String>> remoteRegionAppWhitelist;
//......
}
so,在eureka server工程中加入以下配置:
import com.netflix.discovery.EurekaClientConfig; import com.netflix.eureka.EurekaServerConfig; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration; import org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; /** * 配置类 */ @Configuration @AutoConfigureBefore(EurekaServerAutoConfiguration.class)//当前配置类EurekaServerAutoConfiguration加载完毕后的后续加载操作 public class RegionConfig { @Bean @ConditionalOnMissingBean public EurekaServerConfig eurekaServerConfig(EurekaClientConfig clientConfig) { EurekaServerConfigBean server = new EurekaServerConfigBean(); if (clientConfig.shouldRegisterWithEureka()) { server.setRegistrySyncRetries(5); } server.setRemoteRegionAppWhitelist(new HashMap<>()); return server; } }
1.4、启动实例,执行命令:
mvn spring-boot:run -Dspring.profiles.active=zone1 mvn spring-boot:run -Dspring.profiles.active=zone2 mvn spring-boot:run -Dspring.profiles.active=zone3-region-west mvn spring-boot:run -Dspring.profiles.active=zone4-region-west
2、Eureka Client工程
2.1、eureka client工程pom依赖:
<!--加上文章头部公共依赖-->
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2.2、eureka client工程启动类:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class EurekaClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); } }
2.3、eureka client工程配置文件
这里配置4个client实例,也是分4个zone,属于region-east、region-west两个区。
属于region-east的配置文件为:application-zone1.yml,application-zone2.yml
application-zone1.yml:
server: port: 8071 spring: application.name: demo-client eureka: client: prefer-same-zone-eureka: true region: region-east service-url: zone1: http://localhost:8761/eureka/ zone2: http://localhost:8762/eureka/ availability-zones: region-east: zone1,zone2 instance: metadataMap.zone: zone1
application-zone2.yml
server: port: 8072 spring: application.name: demo-client eureka: client: prefer-same-zone-eureka: true region: region-east service-url: zone1: http://localhost:8761/eureka/ zone2: http://localhost:8762/eureka/ availability-zones: region-east: zone1,zone2 instance: metadataMap.zone: zone2
属于region-west的配置文件为:application-zone3.yml,application-zone4.yml
application-zone3.yml:
server: port: 8073 spring: application.name: demo-client eureka: client: prefer-same-zone-eureka: true region: region-west service-url: zone3: http://localhost:8763/eureka/ zone4: http://localhost:8764/eureka/ availability-zones: region-west: zone3,zone4 instance: metadataMap.zone: zone3
application-zone4.yml:
server: port: 8074 spring: application.name: demo-client eureka: client: prefer-same-zone-eureka: true region: region-west service-url: zone3: http://localhost:8763/eureka/ zone4: http://localhost:8764/eureka/ availability-zones: region-west: zone3,zone4 instance: metadataMap.zone: zone4
application.yml:
management:
endpoints:
web:
exposure:
include: '*'
2.4、启动eureka client工程,执行命令:
mvn spring-boot:run -Dspring.profiles.active=zone1 mvn spring-boot:run -Dspring.profiles.active=zone2 mvn spring-boot:run -Dspring.profiles.active=zone3 mvn spring-boot:run -Dspring.profiles.active=zone4
3、Zuul Gateway工程
3.1、zuul gateway工程pom依赖:
<!--加上文章头部的公共依赖-->
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
3.2、zuul gateway工程启动类:
package cn.springcloud.book; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy @EnableDiscoveryClient public class ZuulGatewayApplication { public static void main(String[] args) { SpringApplication.run(ZuulGatewayApplication.class, args); } }
3.3、zuul gateway工程配置文件,这里使用2个gateway实例来演示fallback到remote region的应用实例功能,配置文件一个属于region-east,一个属于region-west。
application.yml:
spring: application: name: zuul-gateway management: endpoints: web: exposure: include: '*'
application-zone1.yml:
server: port: 10001 eureka: instance: metadataMap.zone: zone1 client: register-with-eureka: true fetch-registry: true region: region-east service-url: zone1: http://localhost:8761/eureka/ zone2: http://localhost:8762/eureka/ availability-zones: region-east: zone1,zone2
application-zone3-region-west.yml:
server: port: 10002 eureka: instance: metadataMap.zone: zone3 client: register-with-eureka: true fetch-registry: true region: region-west service-url: zone3: http://localhost:8763/eureka/ zone4: http://localhost:8764/eureka/ availability-zones: region-west: zone3,zone4
3.4、启动gateway工程,执行命令:
mvn spring-boot:run -Dspring.profiles.active=zone1 mvn spring-boot:run -Dspring.profiles.active=zone3-region-west
访问:localhost:10001/demo-client/actuator/env,结果如下:
访问:localhost:10002/demo-client/actuator/env,结果如下:
可以看到ZoneAffinity特性(上一篇文章有讲),zone1的gateway访问的是zone1的demo-client,zone3的gateway访问的是zone3的demo-client。
接下来,关闭eureka-client的zone1实例,继续访问 localhost:10001/demo-client/actuator/env,可以看到在经过几个错误之后,自动fallback到了remote-region的zone4实例上,实现了类似异地多活自动转移请求的效果。