Eureka获取IP地址逻辑
2019-08-04 22:39 深蓝大道 阅读(2388) 评论(0) 编辑 收藏 举报在Eureka中如果不指定任何的Ip参数的话,那么提供者注册到Eureka中,消费者进行消费的时候访问的Ip为部署Eureka服务器的Ip地址。
那么正常情况下,服务器A调用将会调到服务B的身上,而此时如果在服务B中加入了一下的参数。那么就变了
eureka.instance.prefer-ip-address=true eureka.instance.ip-address=172.12.9.0
此时服务C和服务B是相同的服务,部署在不同的服务器中,Ip地址不同,那么此时调用的服务将会被Eureka转发到服务C中。
源代码详解
我们可以在EurekaClientAutoConfiguration
类中找到eurekaInstanceConfigBean
方法。发现他在程序启动的时候就会加载一些eureka的配置信息
此时我们看到
String ipAddress = this.getProperty("eureka.instance.ip-address");就是在这进行设置的,此时如果没有设置
eureka.instance.ip-address
参数的时候,那么此ipAddress是从EurekaInstanceConfigBean中初始化的。在配置bean中是通过网卡获取相关IP地址的。如果IP地址还是没获取到的话,再获取本机的IP地址。EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
public InetUtils.HostInfo findFirstNonLoopbackHostInfo() { InetAddress address = this.findFirstNonLoopbackAddress(); if (address != null) { return this.convertAddress(address); } else { InetUtils.HostInfo hostInfo = new InetUtils.HostInfo(); hostInfo.setHostname(this.properties.getDefaultHostname()); hostInfo.setIpAddress(this.properties.getDefaultIpAddress()); return hostInfo; } }
public InetAddress findFirstNonLoopbackAddress() {
InetAddress result = null;
try {
int lowest = 2147483647;
Enumeration nics = NetworkInterface.getNetworkInterfaces();
label61:
while(true) {
NetworkInterface ifc;
do {
while(true) {
do {
if (!nics.hasMoreElements()) {
break label61;
}
ifc = (NetworkInterface)nics.nextElement();
} while(!ifc.isUp());
this.log.trace("Testing interface: " + ifc.getDisplayName());
if (ifc.getIndex() >= lowest && result != null) {
if (result != null) {
continue;
}
break;
}
lowest = ifc.getIndex();
break;
}
} while(this.ignoreInterface(ifc.getDisplayName()));
Enumeration addrs = ifc.getInetAddresses();
while(addrs.hasMoreElements()) {
InetAddress address = (InetAddress)addrs.nextElement();
if (address instanceof Inet4Address && !address.isLoopbackAddress() && this.isPreferredAddress(address)) {
this.log.trace("Found non-loopback interface: " + ifc.getDisplayName());
result = address;
}
}
}
} catch (IOException var8) {
this.log.error("Cannot get first non-loopback address", var8);
}
if (result != null) {
return result;
} else {
try {
return InetAddress.getLocalHost();
} catch (UnknownHostException var7) {
this.log.warn("Unable to retrieve localhost");
return null;
}
}
}
通过源码可以看出,该工具类会获取所有网卡,依次进行遍历,取ip地址合理、索引值最小且不在忽略列表的网卡的ip地址作为结果。如果仍然没有找到合适的IP, 那么就将
InetAddress.getLocalHost()
做为最后的fallback方案。 如果以上方法都无法获取IP地址的话,那就使用默认的:127.0.0.1
手动忽略网卡设置:
spring.cloud.inetutils.ignored-interfaces=eth0