Building an example application

To enable zone handling, we need to perform some changes in the client's and gateway's configuration settings. Here's a modified application.yml file from the client application:

spring:
profiles: zone1
eureka:
instance:
metadataMap:
zone: zone1
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/

The only thing that had to be updated is the eureka.instance.metadataMap.zone property, where we set the names of the zone and our service had been registered. 

More changes have to be made in the gateway configuration. First, we need to add three profiles to be able to run an application registered in three different zones and three different discovery servers. Now when launching the gateway application, we should set the VM argument -Dspring.profiles.active=zone[n] to select the right profile. Similar to client-service, we also had to add the eureka.instance.metadataMap.zone property within the configuration settings. There is also one property, eureka.client.preferSameZoneEureka, used for the first time in the example, which had to be equal to true if the gateway should prefer instances of the client application registered in the same zone:

spring:
profiles: zone1
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
registerWithEureka: false
preferSameZoneEureka: true
instance:
metadataMap:
zone: zone1
server:
port: ${PORT:8765}

---
spring:
profiles: zone2
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8762/eureka/
registerWithEureka: false
preferSameZoneEureka: true
instance:
metadataMap:
zone: zone2
server:
port: ${PORT:8766}

---
spring:
profiles: zone3
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8763/eureka/
registerWithEureka: false
preferSameZoneEureka: true
instance:
metadataMap:
zone: zone3
server:
port: ${PORT:8767}

After launching all of the instances of discovery, client, and gateway applications, we can try to call endpoints available under the http://localhost:8765/api/client/ping, http://localhost:8766/api/client/ping, and http://localhost:8767/api/client/ping addresses. Every one of them would always be communicating with the client instance registered in the same zone. So in contrast to tests without a preferred zone, for example, the first instance of gateway available under port 8765 always prints I'm in zone zone1 while calling the ping endpoint:

What will happen when client #1 is not available? The incoming requests would be load balanced 50/50 between two other instances of the client application, because they are both in different zones than gateway #1