本文導讀
1、《Spring Boot 搭建 Eureka Servrer · 單機模式》中已經搭建好了 Eureka Server
2、看本文的同時可以結合 Spring Cloud Netflix 官網文檔:Service Discovery: Eureka Clients
理解
Eureka的Endpoint和解析器
- EndPoint ,服務端點。例如,Eureka-Server 的訪問地址。
- EndPoint 解析器,將配置的 Eureka-Server 的訪問地址解析成 EndPoint 。
目前有多種 Eureka-Server 訪問地址的配置方式,本文只分享 Eureka 1.x 的配置,不包含 Eureka 1.x 對 Eureka 2.x 的兼容配置:
- 第一種,直接配置實際訪問地址。例如,
eureka.serviceUrl.defaultZone=http://127.0.0.1:8080/v2
。 - 第二種,基於 DNS 解析出訪問地址。例如,
eureka.shouldUseDns=true
並且eureka.eurekaServer.domainName=eureka.iocoder.cn
。
- 紅色部分 —— EndPoint
- 黃色部分 —— EndPoint 解析器
問題場景
項目整合了Eureka和springAdmin.本地服務測試的時候,指定是eth0的ip地址,在本地服務啟動,注冊到Eureka服務都是localhost,而不是指定ip地址,導致其他服務無法調用.到其他機器上部署卻能正確注冊為ip.
嘗試在配置上指定使用的ip
spring.boot.admin.client.instance.service-base-url={ip}
無法解決,依然為localhost
再次嘗試用
eureka.instance.hostname={ip}
依然無法解決
問題原因
查看Eureka源碼,連接http://www.itmuch.com/spring-cloud-code-read/spring-cloud-code-read-eureka-registry-ip/
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 InetUtils.HostInfo convertAddress(final InetAddress address) {
InetUtils.HostInfo hostInfo = new InetUtils.HostInfo();
Future result = this.executorService.submit(new Callable<String>() {
public String call() throws Exception {
return address.getHostName();
}
});
String hostname;
try {
hostname = (String)result.get((long)this.properties.getTimeoutSeconds(), TimeUnit.SECONDS);
} catch (Exception var6) {
this.log.info("Cannot determine local hostname");
hostname = "localhost";
}
hostInfo.setHostname(hostname);
hostInfo.setIpAddress(address.getHostAddress());
return hostInfo;
}
可以看出注冊服務的時候,回去解析服務器上的網卡信息,在DNS解析超時便會使用localhost代替.其默認時間為1s
spring.cloud.inetutils.timeout-seconds=1
解決方法
1:設置合理DNS解析時間,過長則會效率慢
2:修改為正確的DNS