《重新定义Spring Cloud实战》——3.5.3 支持Remote Region
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的。
- 点赞
- 收藏
- 关注作者
评论(0)