若是没有针对多网卡作特别的配置的话,上面看到的192.168.239.1:8080和其连接的URL地址多半不是一个字符串;spring
咱们在配置Eureka Client的时候想要实现的效果是:上面显示192.168.239.1:8080的地方,显示IP地址和端口号,其URL地址的host和port与这里显示的IP地址和端口号一致。同时在多网卡的状况下,咱们能够任意选择Spring Cloud App想要使用的网卡。docker
Spring Cloud 网卡选择一文中,给出了一个多网卡配置的解决方案:app
spring.cloud.inetutils.preferred-networks: 192.168.239.
eureka.instance.prefer-ip-address:true
经过设置这两个属性,URL地址的host的值就是咱们想要的IP地址了。
经过查看spring-cloud-netflix-eureka-server包下面的status.ftl文件,发现显示的文本是instance的id。ide
<#list instanceInfo.instances as instance>
<#if instance.isHref>
<a href="${instance.url}" target="_blank">${instance.id}</a>
<#else>
${instance.id}
</#if><#if instance_has_next>,</#if>
</#list>
因此咱们只要给instance-id赋值为ip:port就好了:oop
eureka.instance.instance-id:${spring.cloud.client.ipAddress}:${server.port}
1
spring.cloud.client.ipAddress这个是怎么来的呢?看下HostInfoEnvironmentPostProcessor这个类,这个类是EnvironmentPostProcessor接口的实现:post
@Override www.1b23.com
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("spring.cloud.client.hostname", hostInfo.getHostname());
map.put("spring.cloud.client.ipAddress", hostInfo.getIpAddress());
MapPropertySource propertySource = new MapPropertySource(
"springCloudClientHostInfo", map);
environment.getPropertySources().addLast(propertySource);
}
这时候问题来了,若是这么设置,会发现显示的内容和其连接地址不同,经过调成程序发现,显示的时候的host和port和链接地址里的host和port虽然都是经过InetUtils获取的,可是执行的时间点不同,执行的时候的上下文信息不同。this
首先HostInfoEnvironmentPostProcessor的执行时间点能够参看Spring Boot # EnvironmentPostProcessor,虽然咱们配置了spring.cloud.inetutils.preferred-networks: 192.168.239.,可是此时这个application.xml文件的内容还没被加载,HostInfoEnvironmentPostProcessor在执行的时候,上下文里就没有这个配置,因此在执行:url
InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);
1
时候,environment中没有spring.cloud.inetutils.preferred-networks: 192.168.239.这个配置。.net
EurekaClientAutoConfiguration中的eurekaInstanceConfigBean方法会构造并返回一个EurekaInstanceConfigBean,EurekaInstanceConfigBean的构造方法以下:server
public EurekaInstanceConfigBean(InetUtils inetUtils) {
this.inetUtils = inetUtils;
this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo();
this.ipAddress = this.hostInfo.getIpAddress();
this.hostname = this.hostInfo.getHostname();
}
在这个时间点,application.yml中的配置已经加载,spring boot的配置文件在容器建立以前就全加载完了,具体参看Spring Boot # EnvironmentPostProcessor,spring.cloud.inetutils.preferred-networks: 192.168.239.的信息已经有了,因此此配置就会生效,从而选择出可能跟以前不同的IP地址。
结论 eureka设置 eureka.instance.prefer-ip-address: true eureka.instance.instance-id: ${spring.cloud.client.ipAddress}:${server.port} spring.cloud.inetutils.preferred-networks设置 将spring.cloud.inetutils.preferred-networks的配置从application.yml文件移到外部,jar命令-Dspring.cloud.inetutils.preferred-networks: 192.168.239.覆盖或者设置在系统的环境变量里。用dockerfile或者docker compose就更方便了。