Eureka实战-3【支持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实例上,实现了类似异地多活自动转移请求的效果。