多個ip到底用哪個忱屑?
上次說到instanceinfo的hostname蹬敲,ip,那么這些值是從哪來的呢想幻?
public EurekaInstanceConfigBean(InetUtils inetUtils) {
this.inetUtils = inetUtils;
this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo();
this.ipAddress = this.hostInfo.getIpAddress();
this.hostname = this.hostInfo.getHostname();
}
可以看到是從InetUtils類獲取的,而這個類是從InetUtilsProperties獲取數(shù)據(jù)
及從配置文件spring.cloud.inetutils
開頭的配置獲取话浇。
你可以設(shè)置忽略的網(wǎng)卡脏毯,或者優(yōu)先選擇的網(wǎng)卡,這兩個設(shè)置都支持正則
// @formatter:off
if (!ignoreInterface(ifc.getDisplayName())) {
for (Enumeration<InetAddress> addrs = ifc
.getInetAddresses(); addrs.hasMoreElements();) {
InetAddress address = addrs.nextElement();
if (address instanceof Inet4Address
&& !address.isLoopbackAddress()
&& isPreferredAddress(address)) {
log.trace("Found non-loopback interface: "
+ ifc.getDisplayName());
result = address;
}
}
}
// @formatter:on
如果這兩個設(shè)置你都不滿意幔崖,你可以設(shè)置忽略值為.*
食店,忽略所有網(wǎng)卡
然后用hostname從/etc/hosts中獲取ip,也就是說你要在/etc/hosts設(shè)置你的ip對應(yīng)的本機(jī)hostname
如果你認(rèn)為這樣就完事了赏寇,那就是大錯特錯吉嫩。
通過查找InetUtils.findFirstNonLoopbackAddress引用發(fā)現(xiàn),在HostInfoEnvironmentPostProcessor類中嗅定,并未使用配置文件的參數(shù)自娩,而是直接創(chuàng)建了一個對象。
@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.ip-address", hostInfo.getIpAddress());
MapPropertySource propertySource = new MapPropertySource(
"springCloudClientHostInfo", map);
environment.getPropertySources().addLast(propertySource);
}
private HostInfo getFirstNonLoopbackHostInfo(ConfigurableEnvironment environment) {
InetUtilsProperties target = new InetUtilsProperties();
ConfigurationPropertySources.attach(environment);
Binder.get(environment).bind(InetUtilsProperties.PREFIX,
Bindable.ofInstance(target));
try (InetUtils utils = new InetUtils(target)) {
return utils.findFirstNonLoopbackHostInfo();
}
}
雖然是new了一個對象渠退,但是其實使用了environment設(shè)置了屬性忙迁,那么我們有兩種方案。
- 在啟動參數(shù)中傳入?yún)?shù)碎乃,比如--spring.cloud.inetutils.ignoredInterfaces=.*
- 創(chuàng)建一個EnvironmentPostProcessor類姊扔,并且該類的order要比HostInfoEnvironmentPostProcessor小,及優(yōu)先加載我們定義的
public class InspectEurekaClientIp implements BeanPostProcessor, EnvironmentPostProcessor, Ordered {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Map<String, Object> ignoredInterfaces = Maps.newHashMap();
ignoredInterfaces.put("spring.cloud.inetutils.ignoredInterfaces", Lists.newArrayList(".*"));
SystemEnvironmentPropertySource systemEnvironmentPropertySource = new SystemEnvironmentPropertySource("systemEnvironment", ignoredInterfaces);
environment.getPropertySources().addLast(systemEnvironmentPropertySource);
}
@Override
public int getOrder() {
return ConfigFileApplicationListener.DEFAULT_ORDER - 2;
}
}
還要創(chuàng)建META-INF/spring.factories文件
org.springframework.boot.env.EnvironmentPostProcessor=\
上述類名