Eureka实战-3【支持Remote Region】

2022-10-14,,,,

工程公共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实例上,实现了类似异地多活自动转移请求的效果。

 

《Eureka实战-3【支持Remote Region】.doc》

下载本文的Word格式文档,以方便收藏与打印。