《重新定义Spring Cloud实战》——3.5.3 支持Remote Region

举报
华章计算机 发表于 2019/06/04 15:13:52 2019/06/04
【摘要】 本书摘自《重新定义Spring Cloud实战》——书中第3章,第3.5.3节,作者是许进、叶志远、钟尊发、蔡波斯、方志朋、郭芳碧、朱德明。

3.5.3 支持Remote Region

1. Eureka Server实例

这里我们配置4个Eureka Server,分4个zone,然后属于region-east、region-west两个region,其region-east的配置文件如代码清单3-18、3-19所示:

代码清单3-18 ch3-3\ch3-3-eureka-server\src\main\resources\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

代码清单3-19 ch3-3\ch3-3-eureka-server\src\main\resources\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

这里zone1及zone2属于region-east,配置其remote-region为region-west,具体如代码清单3-20、代码清单3-21所示。

代码清单3-20 ch3-3\ch3-3-eureka-server\src\main\resources\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

代码清单3-21 ch3-3\ch3-3-eureka-server\src\main\resources\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

这里zone3及zone4属于region-west,配置其remote-region为region-east。

由于源码里EurekaServerConfigBean的remoteRegionAppWhitelist默认为null,而getRemoteRegionAppWhitelist(String regionName)方法会直接调用,如果不设置,则会报空指针异常:

2018-06-25 16:09:43.414 ERROR 13032 --- [nio-8764-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception


java.lang.NullPointerException: null

    at org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean.getRemoteRegionAppWhitelist(EurekaServerConfigBean.java:226) ~[spring-cloud-netflix-eureka-server-2.0.0.RELEASE.jar:2.0.0.RELEASE]

    at com.netflix.eureka.registry.AbstractInstanceRegistry.shouldFetchFromRemoteRegistry(AbstractInstanceRegistry.java:795) ~[eureka-core-1.9.2.jar:1.9.2]

    at com.netflix.eureka.registry.AbstractInstanceRegistry.getApplicationsFromMultipleRegions(AbstractInstanceRegistry.java:767) ~[eureka-core-1.9.2.jar:1.9.2]

    at com.netflix.eureka.registry.AbstractInstanceRegistry.getApplicationsFromAllRemoteRegions(AbstractInstanceRegistry.java:702) ~[eureka-core-1.9.2.jar:1.9.2]

    at com.netflix.eureka.registry.AbstractInstanceRegistry.getApplications(AbstractInstanceRegistry.java:693) ~[eureka-core-1.9.2.jar:1.9.2]

    at com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl.getSortedApplications(PeerAwareInstanceRegistryImpl.java:555) ~[eureka-core-1.9.2.jar:1.9.2]

为了避免空指针,需要初始下该对象,如代码清单3-22所示:

代码清单3-22 ch3-3\ch3-3-eureka-server\src\main\java\cn\springcloud\book\config\RegionConfig.java

@Configuration

@AutoConfigureBefore(EurekaServerAutoConfiguration.class)

public class RegionConfig {


    @Bean

    @ConditionalOnMissingBean

    public EurekaServerConfig eurekaServerConfig(EurekaClientConfig clientConfig) {

        EurekaServerConfigBean server = new EurekaServerConfigBean();

        if (clientConfig.shouldRegisterWithEureka()) {

            // Set a sensible default if we are supposed to replicate

            server.setRegistrySyncRetries(5);

        }

        server.setRemoteRegionAppWhitelist(new HashMap<>());

        return server;

    }

}

然后使用如下命令启动4个Eureka Server:

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实例

这里我们配置4个Eureka Client,也是分了4个zone,属于region-east、region-west两个region。其region-east的配置文件如代码清单3-23、3-24所示:

代码清单3-23 ch3-3\ch3-3-eureka-client\src\main\resources\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

代码清单3-24 ch3-3\ch3-3-eureka-client\src\main\resources\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

zone1及zone2属于region-east,zone3及zone4属于region-west,具体如代码清单3-25、3-26所示。

代码清单3-25 ch3-3\ch3-3-eureka-client\src\main\resources\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

代码清单3-26 ch3-3\ch3-3-eureka-client\src\main\resources\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

然后使用如下命令启动4个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实例

这里我们使用2个zuul gateway实例来演示fallback到remote region的应用实例的功能。这两个gateway,一个属于region-east,一个属于region-west。其配置分别如代码清单3-27、3-28所示:

代码清单3-27 ch3-3\ch3-3-3-zuul-gateway \src\main\resources\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

代码清单3-28 ch3-3\ch3-3-zuul-gateway \src\main\resources\application-zone.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

然后使用如下命令启动gateway:

mvn spring-boot:run –Dspring.profiles.active=zone1

mvn spring-boot:run –Dspring.profiles.active=zone3-region-west

启动之后访问:

curl –i http://localhost:10001/demo-client/actuator/env

curl –i http://localhost:10002/demo-client/actuator/env

可以看到如3.5.2节讲的zoneAffinity特性,zone1的gateway访问的是zone1的demo-client,zone3的gateway访问的是zone3的demo-client。

接下来关闭到zone1及zone2的Eureka Client,再继续访问curl –i http://localhost:10001/demo-client/actuator/env,可以看到经过几个报错之后,自动fallback到了remote-region的zone3或者zone4的实例,实现了类似异地多活自动转移请求的效果。有兴趣的读者可以阅读相关源码,看下Eureka Server到底是怎么实现跨region的fallback的。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。