Engineering public pom dependence
<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. Ereka server project
1.1. Ereka server project pom dependence:
<!--Plus the public dependence on the header of the article-->
<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. Project Startup Class:
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. Four instances of eureka server are configured here. The paths are: eureka-server src main resources divided into four zone s, which belong to region-east and region-west.
The configuration files belonging to region-east are: application-zone 1.yml, application-zone 2.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
The configuration files belonging to region-west are: application-zone 3-region-west.yml, application-zone 4-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
Because in the framework, the default value of Eureka Server ConfigBean's remoteRegionAppWhitelist is null, and the getRemoteRegionAppWhitelist(String regionName) method is called directly, if it is not handled in the project, the direct null pointer exception will occur.
//Frame source
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, in the eureka server project, add the following configuration:
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 class */ @Configuration @AutoConfigureBefore(EurekaServerAutoConfiguration.class)//Current configuration class EurekaServerAutoConfiguration Follow-up Loading after Loading 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. Start the instance and execute the command:
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 Project
2.1. Ereka Client project pom dependence:
<!--Plus article header public dependency-->
<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. Ereka Client Project Startup Class:
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. Ereka Client Engineering Configuration File
There are four client instances, which are also divided into four zone s, belonging to region-east and region-west.
The configuration files belonging to region-east are: application-zone 1.yml, application-zone 2.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
The configuration files belonging to region-west are: application-zone 3.yml, application-zone 4.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. Start the eureka client project and execute the order:
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 Project
3.1. zuul gateway project pom dependence:
<!--Plus the public dependence on the header of the article-->
<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 project startup class:
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 project configuration file. Two gateway instances are used to demonstrate the application instance function of fallback to remote region. One belongs to region-east and the other belongs to 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. Start the gateway project and execute the command:
mvn spring-boot:run -Dspring.profiles.active=zone1 mvn spring-boot:run -Dspring.profiles.active=zone3-region-west
Visit: localhost:10001/demo-client/actuator/env. The results are as follows:
Visit: localhost:10002/demo-client/actuator/env, the results are as follows:
You can see the Zone Affinity feature( As mentioned in the last article The gateway of zone 1 accesses demo-client of zone 1, and the gateway of zone 3 accesses demo-client of zone 3.
Next, close the zone 1 instance of eureka-client and continue visiting localhost:10001/demo-client/actuator/env. You can see that after several errors, automatic fallback is implemented on the zone 4 instance of remote-region, which achieves the effect similar to remote multi-activity automatic transfer request.