Commit 4c517913 by Dave Syer

Add metadataMap option for Server.zone

Adds a metadataMap for the Server.zone so that user can provide the data through external configuration if needed.
parent 4afc44ac
...@@ -235,6 +235,9 @@ By default every Eureka server is also a Eureka client and requires ...@@ -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 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. of noise about not being able to register with the peer.
See also <<spring-cloud-ribbon,below for details of Ribbon
support>> on the client side for Zones and Regions.
=== Standalone Mode === Standalone Mode
The combination of the two caches (client and server) and the The combination of the two caches (client and server) and the
...@@ -495,11 +498,22 @@ This replaces the `NoOpPing` with `PingUrl`. ...@@ -495,11 +498,22 @@ This replaces the `NoOpPing` with `PingUrl`.
=== Using the Ribbon with Eureka === Using the Ribbon with Eureka
When Eureka is used in conjunction with Ribbon the `ribbonServerList` is When Eureka is used in conjunction with Ribbon the `ribbonServerList`
overridden with an extension of `DiscoveryEnabledNIWSServerList` which is overridden with an extension of `DiscoveryEnabledNIWSServerList`
populates the list of servers from Eureka. It also replaces the `IPing` which populates the list of servers from Eureka. It also replaces the
interface with `NIWSDiscoveryPing` which delegates to Eureka to determine if `IPing` interface with `NIWSDiscoveryPing` which delegates to Eureka
a server is up. 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]] [[spring-cloud-ribbon-without-eureka]]
=== Example: How to Use Ribbon Without Eureka === Example: How to Use Ribbon Without Eureka
......
...@@ -51,13 +51,15 @@ public class DomainExtractingServerList implements ServerList<DiscoveryEnabledSe ...@@ -51,13 +51,15 @@ public class DomainExtractingServerList implements ServerList<DiscoveryEnabledSe
@Override @Override
public List<DiscoveryEnabledServer> getInitialListOfServers() { public List<DiscoveryEnabledServer> getInitialListOfServers() {
List<DiscoveryEnabledServer> servers = setZones(this.list.getInitialListOfServers()); List<DiscoveryEnabledServer> servers = setZones(this.list
.getInitialListOfServers());
return servers; return servers;
} }
@Override @Override
public List<DiscoveryEnabledServer> getUpdatedListOfServers() { public List<DiscoveryEnabledServer> getUpdatedListOfServers() {
List<DiscoveryEnabledServer> servers = setZones(this.list.getUpdatedListOfServers()); List<DiscoveryEnabledServer> servers = setZones(this.list
.getUpdatedListOfServers());
return servers; return servers;
} }
...@@ -68,8 +70,8 @@ public class DomainExtractingServerList implements ServerList<DiscoveryEnabledSe ...@@ -68,8 +70,8 @@ public class DomainExtractingServerList implements ServerList<DiscoveryEnabledSe
boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean( boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean(
CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE); CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE);
for (DiscoveryEnabledServer server : servers) { for (DiscoveryEnabledServer server : servers) {
result.add(new DomainExtractingServer(server, result.add(new DomainExtractingServer(server, isSecure, shouldUseIpAddr,
isSecure, shouldUseIpAddr, this.approximateZoneFromHostname)); this.approximateZoneFromHostname));
} }
return result; return result;
} }
...@@ -86,7 +88,10 @@ class DomainExtractingServer extends DiscoveryEnabledServer { ...@@ -86,7 +88,10 @@ class DomainExtractingServer extends DiscoveryEnabledServer {
boolean useIpAddr, boolean approximateZoneFromHostname) { boolean useIpAddr, boolean approximateZoneFromHostname) {
// host and port are set in super() // host and port are set in super()
super(server.getInstanceInfo(), useSecurePort, useIpAddr); super(server.getInstanceInfo(), useSecurePort, useIpAddr);
if (approximateZoneFromHostname) { if (server.getInstanceInfo().getMetadata().containsKey("zone")) {
setZone(server.getInstanceInfo().getMetadata().get("zone"));
}
else if (approximateZoneFromHostname) {
setZone(extractApproximateZone(server)); setZone(extractApproximateZone(server));
} }
else { else {
......
...@@ -18,7 +18,9 @@ package org.springframework.cloud.netflix.ribbon.eureka; ...@@ -18,7 +18,9 @@ package org.springframework.cloud.netflix.ribbon.eureka;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.junit.Test; import org.junit.Test;
...@@ -50,6 +52,9 @@ public class DomainExtractingServerListTests { ...@@ -50,6 +52,9 @@ public class DomainExtractingServerListTests {
static final String INSTANCE_ID = "myInstanceId"; static final String INSTANCE_ID = "myInstanceId";
private Map<String, String> metadata = Collections.<String, String> singletonMap(
"instanceId", INSTANCE_ID);
@Test @Test
public void testDomainExtractingServer() { public void testDomainExtractingServer() {
DomainExtractingServerList serverList = getDomainExtractingServerList( DomainExtractingServerList serverList = getDomainExtractingServerList(
...@@ -62,6 +67,20 @@ public class DomainExtractingServerListTests { ...@@ -62,6 +67,20 @@ public class DomainExtractingServerListTests {
} }
@Test @Test
public void testZoneInMetaData() {
this.metadata = new HashMap<String, String>();
this.metadata.put("zone", "us-west-1");
this.metadata.put("instanceId", INSTANCE_ID);
DomainExtractingServerList serverList = getDomainExtractingServerList(
new DefaultClientConfigImpl(), false);
List<DiscoveryEnabledServer> 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() { public void testDomainExtractingServerDontApproximateZone() {
DomainExtractingServerList serverList = getDomainExtractingServerList( DomainExtractingServerList serverList = getDomainExtractingServerList(
new DefaultClientConfigImpl(), false); new DefaultClientConfigImpl(), false);
...@@ -104,8 +123,7 @@ public class DomainExtractingServerListTests { ...@@ -104,8 +123,7 @@ public class DomainExtractingServerListTests {
InstanceInfo instanceInfo = mock(InstanceInfo.class); InstanceInfo instanceInfo = mock(InstanceInfo.class);
given(server.getInstanceInfo()).willReturn(instanceInfo); given(server.getInstanceInfo()).willReturn(instanceInfo);
given(server.getHost()).willReturn(HOST_NAME); given(server.getHost()).willReturn(HOST_NAME);
given(instanceInfo.getMetadata()).willReturn( given(instanceInfo.getMetadata()).willReturn(this.metadata);
Collections.<String, String> singletonMap("instanceId", INSTANCE_ID));
given(instanceInfo.getHostName()).willReturn(HOST_NAME); given(instanceInfo.getHostName()).willReturn(HOST_NAME);
given(instanceInfo.getIPAddr()).willReturn(IP_ADDR); given(instanceInfo.getIPAddr()).willReturn(IP_ADDR);
given(instanceInfo.getPort()).willReturn(PORT); given(instanceInfo.getPort()).willReturn(PORT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment