Spring Cloud Eureka 多网卡配置最终版

发博词

完美解决Spring Cloud App中在多网卡环境下使用Eureka的问题。欢迎留言讨论。

预备

Spring Cloud 网卡选择

前因后果

整个Spring Cloud所有组件的本机网络信息都是也都必须是使用org.springframework.cloud.commons.util.InetUtil来获取。

我们在查看注册到Eureka Server上的Eureka Client的信息的时候,可以看到如下的界面:

这里写图片描述

如果没有针对多网卡做特别的配置的话,上面看到的192.168.239.1:8080和其链接的URL地址多半不是一个字符串;

我们在配置Eureka Client的时候想要实现的效果是:上面显示192.168.239.1:8080的地方,显示IP地址和端口号,其URL地址的host和port与这里显示的IP地址和端口号一致。同时在多网卡的情况下,我们可以任意选择Spring Cloud App想要使用的网卡。

Spring Cloud 网卡选择一文中,给出了一个多网卡配置的解决方案:

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。

<#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就行了:

eureka.instance.instance-id:${spring.cloud.client.ipAddress}:${server.port}

spring.cloud.client.ipAddress这个是怎么来的呢?看下HostInfoEnvironmentPostProcessor这个类,这个类是EnvironmentPostProcessor接口的实现:

@Override
	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获取的,但是执行的时间点不一样,执行的时候的上下文信息不一样。

首先HostInfoEnvironmentPostProcessor的执行时间点可以参看Spring Boot # EnvironmentPostProcessor,虽然我们配置了spring.cloud.inetutils.preferred-networks: 192.168.239.,但是此时这个application.xml文件的内容还没被加载,HostInfoEnvironmentPostProcessor在执行的时候,上下文里就没有这个配置,所以在执行:

InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);

时候,environment中没有spring.cloud.inetutils.preferred-networks: 192.168.239.这个配置。

EurekaClientAutoConfiguration中的eurekaInstanceConfigBean方法会构造并返回一个EurekaInstanceConfigBean,EurekaInstanceConfigBean的构造方法如下:

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就更方便了。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈振阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值