在Eureka中如果不指定任何的Ip参数的话,那么提供者注册到Eureka中,消费者进行消费的时候访问的Ip为部署Eureka服务器的Ip地址。
Eureka不加参数调用图
那么正常情况下,服务器A调用将会调到服务B的身上,而此时如果在服务B中加入了一下的参数。那么就变了
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=172.12.9.0
此时服务C和服务B是相同的服务,部署在不同的服务器中,Ip地址不同,那么此时调用的服务将会被Eureka转发到服务C中。
image
我们可以在EurekaClientAutoConfiguration
类中找到eurekaInstanceConfigBean
方法。发现他在程序启动的时候就会加载一些eureka的配置信息
@Bean
@ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils,
ManagementMetadataProvider managementMetadataProvider, ConfigurableEnvironment env) throws MalformedURLException {
PropertyResolver environmentPropertyResolver = new RelaxedPropertyResolver(env);
PropertyResolver eurekaPropertyResolver = new RelaxedPropertyResolver(env, "eureka.instance.");
String hostname = eurekaPropertyResolver.getProperty("hostname");
boolean preferIpAddress = Boolean.parseBoolean(eurekaPropertyResolver.getProperty("preferIpAddress"));
String ipAddress = eurekaPropertyResolver.getProperty("ipAddress");
boolean isSecurePortEnabled = Boolean.parseBoolean(eurekaPropertyResolver.getProperty("securePortEnabled"));
String serverContextPath = environmentPropertyResolver.getProperty("server.contextPath", "/");
int serverPort = Integer.valueOf(environmentPropertyResolver.getProperty("server.port", environmentPropertyResolver.getProperty("port", "8080")));
Integer managementPort = environmentPropertyResolver.getProperty("management.port", Integer.class);// nullable. should be wrapped into optional
String managementContextPath = environmentPropertyResolver.getProperty("management.contextPath");// nullable. should be wrapped into optional
Integer jmxPort = environmentPropertyResolver.getProperty("com.sun.management.jmxremote.port", Integer.class);//nullable
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
instance.setNonSecurePort(serverPort);
instance.setInstanceId(getDefaultInstanceId(environmentPropertyResolver));
instance.setPreferIpAddress(preferIpAddress);
instance.setSecurePortEnabled(isSecurePortEnabled);
if (StringUtils.hasText(ipAddress)) {
instance.setIpAddress(ipAddress);
}
if(isSecurePortEnabled) {
instance.setSecurePort(serverPort);
}
if (StringUtils.hasText(hostname)) {
instance.setHostname(hostname);
}
String statusPageUrlPath = eurekaPropertyResolver.getProperty("statusPageUrlPath");
String healthCheckUrlPath = eurekaPropertyResolver.getProperty("healthCheckUrlPath");
if (StringUtils.hasText(statusPageUrlPath)) {
instance.setStatusPageUrlPath(statusPageUrlPath);
}
if (StringUtils.hasText(healthCheckUrlPath)) {
instance.setHealthCheckUrlPath(healthCheckUrlPath);
}
ManagementMetadata metadata = managementMetadataProvider.get(instance, serverPort,
serverContextPath, managementContextPath, managementPort);
if(metadata != null) {
instance.setStatusPageUrl(metadata.getStatusPageUrl());
instance.setHealthCheckUrl(metadata.getHealthCheckUrl());
if(instance.isSecurePortEnabled()) {
instance.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl());
}
Map metadataMap = instance.getMetadataMap();
if (metadataMap.get("management.port") == null) {
metadataMap.put("management.port", String.valueOf(metadata.getManagementPort()));
}
}
setupJmxPort(instance, jmxPort);
return instance;
}
此时我们看到String ipAddress = eurekaPropertyResolver.getProperty("ipAddress");
就是在这进行设置的,此时如果没有设置eureka.instance.ip-address
参数的时候,那么此ipAddress就是本机的Ip。这是如何设置的呢?我们可以看到代码中有这么一句
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
instance.setNonSecurePort(serverPort);
instance.setInstanceId(getDefaultInstanceId(environmentPropertyResolver));
instance.setPreferIpAddress(preferIpAddress);
instance.setSecurePortEnabled(isSecurePortEnabled);
if (StringUtils.hasText(ipAddress)) {
instance.setIpAddress(ipAddress);
}
EurekaInstanceConfigBean
先进行了初始化,我们进入EurekaInstanceConfigBean
的构造参数中看
public EurekaInstanceConfigBean(InetUtils inetUtils) {
this.inetUtils = inetUtils;
this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo();
this.ipAddress = this.hostInfo.getIpAddress();
this.hostname = this.hostInfo.getHostname();
}
可以看到在这进行了初始化ipAddress
参数,其中hostInfo
是如何得到的就进行讲解了,其本质就是为了获取本机的真实IP。到这给Eureka注册中心的注册信息已经准备好了
然后在InstanceInfoReplicator
中调用run方法进行将自己信息注册到远程的Eureka中。
此时就可以看到如果设置eureka.instance.prefer-ip-address
为false时,那么注册到Eureka中的Ip地址就是本机的Ip地址。如果设置了true并且也设置了eureka.instance.ip-address
那么就将此ip地址注册到Eureka中。那么调用的时候,发送的请求目的地就是此Ip地址。
转自:不学无数的程序员
链接:https://www.jianshu.com/p/886947b52cb4