diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 9598b898..27d35034 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -235,6 +235,9 @@ By default every Eureka server is also a Eureka client and requires the service will run and work, but it will shower your logs with a lot of noise about not being able to register with the peer. +See also <> on the client side for Zones and Regions. + === Standalone Mode The combination of the two caches (client and server) and the @@ -495,11 +498,22 @@ This replaces the `NoOpPing` with `PingUrl`. === Using the Ribbon with Eureka -When Eureka is used in conjunction with Ribbon the `ribbonServerList` is -overridden with an extension of `DiscoveryEnabledNIWSServerList` which -populates the list of servers from Eureka. It also replaces the `IPing` -interface with `NIWSDiscoveryPing` which delegates to Eureka to determine if -a server is up. +When Eureka is used in conjunction with Ribbon the `ribbonServerList` +is overridden with an extension of `DiscoveryEnabledNIWSServerList` +which populates the list of servers from Eureka. It also replaces the +`IPing` interface with `NIWSDiscoveryPing` which delegates to Eureka +to determine if a server is up. The `ServerList` that is installed by +default is a `DomainExtractingServerList` and the purpose of this is +to make physical metadata available to the load balancer without using +AWS AMI metadata (which is what Netflix relies on). By default the +server list will be constructed with "zone" information as provided in +the instance metadata (so on the client set +`eureka.instance.metadataMap.zone`), and if that is missing it can use +the domain name from the server hostname as a proxy for zone (if the +flag `approximateZoneFromDomain` is set). Once the zone information is +available it can be used in a `ServerListFilter` (by default it will +be used to locate a server in the same zone as the client because the +default is a `ZonePreferenceServerListFilter`). [[spring-cloud-ribbon-without-eureka]] === Example: How to Use Ribbon Without Eureka diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java index 30d7dcf8..202c2855 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java @@ -51,13 +51,15 @@ public class DomainExtractingServerList implements ServerList getInitialListOfServers() { - List servers = setZones(this.list.getInitialListOfServers()); + List servers = setZones(this.list + .getInitialListOfServers()); return servers; } @Override public List getUpdatedListOfServers() { - List servers = setZones(this.list.getUpdatedListOfServers()); + List servers = setZones(this.list + .getUpdatedListOfServers()); return servers; } @@ -68,8 +70,8 @@ public class DomainExtractingServerList implements ServerList metadata = Collections. singletonMap( + "instanceId", INSTANCE_ID); + @Test public void testDomainExtractingServer() { DomainExtractingServerList serverList = getDomainExtractingServerList( @@ -61,6 +66,20 @@ public class DomainExtractingServerListTests { assertEquals("hostPort was wrong", HOST_NAME + ":" + PORT, des.getHostPort()); } + @Test + public void testZoneInMetaData() { + this.metadata = new HashMap(); + this.metadata.put("zone", "us-west-1"); + this.metadata.put("instanceId", INSTANCE_ID); + DomainExtractingServerList serverList = getDomainExtractingServerList( + new DefaultClientConfigImpl(), false); + List servers = serverList.getInitialListOfServers(); + assertNotNull("servers was null", servers); + assertEquals("servers was not size 1", 1, servers.size()); + DomainExtractingServer des = assertDomainExtractingServer(servers, "us-west-1"); + assertEquals("Zone was wrong", "us-west-1", des.getZone()); + } + @Test public void testDomainExtractingServerDontApproximateZone() { DomainExtractingServerList serverList = getDomainExtractingServerList( @@ -104,8 +123,7 @@ public class DomainExtractingServerListTests { InstanceInfo instanceInfo = mock(InstanceInfo.class); given(server.getInstanceInfo()).willReturn(instanceInfo); given(server.getHost()).willReturn(HOST_NAME); - given(instanceInfo.getMetadata()).willReturn( - Collections. singletonMap("instanceId", INSTANCE_ID)); + given(instanceInfo.getMetadata()).willReturn(this.metadata); given(instanceInfo.getHostName()).willReturn(HOST_NAME); given(instanceInfo.getIPAddr()).willReturn(IP_ADDR); given(instanceInfo.getPort()).willReturn(PORT);