in eureka-client/src/main/java/com/netflix/discovery/endpoint/EndpointUtils.java [95:180]
public static List<String> getServiceUrlsFromDNS(EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone, ServiceUrlRandomizer randomizer) {
String region = getRegion(clientConfig);
// Get zone-specific DNS names for the given region so that we can get a
// list of available zones
Map<String, List<String>> zoneDnsNamesMap = getZoneBasedDiscoveryUrlsFromRegion(clientConfig, region);
Set<String> availableZones = zoneDnsNamesMap.keySet();
List<String> zones = new ArrayList<>(availableZones);
if (zones.isEmpty()) {
throw new RuntimeException("No available zones configured for the instanceZone " + instanceZone);
}
int zoneIndex = 0;
boolean zoneFound = false;
for (String zone : zones) {
logger.debug("Checking if the instance zone {} is the same as the zone from DNS {}", instanceZone, zone);
if (preferSameZone) {
if (instanceZone.equalsIgnoreCase(zone)) {
zoneFound = true;
}
} else {
if (!instanceZone.equalsIgnoreCase(zone)) {
zoneFound = true;
}
}
if (zoneFound) {
logger.debug("The zone index from the list {} that matches the instance zone {} is {}",
zones, instanceZone, zoneIndex);
break;
}
zoneIndex++;
}
if (zoneIndex >= zones.size()) {
if (logger.isWarnEnabled()) {
logger.warn("No match for the zone {} in the list of available zones {}",
instanceZone, zones.toArray());
}
} else {
// Rearrange the zones with the instance zone first
for (int i = 0; i < zoneIndex; i++) {
String zone = zones.remove(0);
zones.add(zone);
}
}
// Now get the eureka urls for all the zones in the order and return it
List<String> serviceUrls = new ArrayList<>();
for (String zone : zones) {
for (String zoneCname : zoneDnsNamesMap.get(zone)) {
List<String> ec2Urls = new ArrayList<>(getEC2DiscoveryUrlsFromZone(zoneCname, DiscoveryUrlType.CNAME));
// Rearrange the list to distribute the load in case of multiple servers
if (ec2Urls.size() > 1) {
randomizer.randomize(ec2Urls);
}
for (String ec2Url : ec2Urls) {
StringBuilder sb = new StringBuilder()
.append("http://")
.append(ec2Url)
.append(":")
.append(clientConfig.getEurekaServerPort());
if (clientConfig.getEurekaServerURLContext() != null) {
if (!clientConfig.getEurekaServerURLContext().startsWith("/")) {
sb.append("/");
}
sb.append(clientConfig.getEurekaServerURLContext());
if (!clientConfig.getEurekaServerURLContext().endsWith("/")) {
sb.append("/");
}
} else {
sb.append("/");
}
String serviceUrl = sb.toString();
logger.debug("The EC2 url is {}", serviceUrl);
serviceUrls.add(serviceUrl);
}
}
}
// Rearrange the fail over server list to distribute the load
String primaryServiceUrl = serviceUrls.remove(0);
randomizer.randomize(serviceUrls);
serviceUrls.add(0, primaryServiceUrl);
if (logger.isDebugEnabled()) {
logger.debug("This client will talk to the following serviceUrls in order : {} ",
(Object) serviceUrls.toArray());
}
return serviceUrls;
}