First, the problem Description
- 172.17.0.2: docker container internal IP address.
- x00001.prod.shunyi.beijing for the server name that is HostName.
- 10.20.30.40: the server IP address, the address we really need.
- $ {Pers.hanchao.ip}: expressed as a placeholder for the IP address of the server, for delivery to docker container.
Normal performance after the successful registration 1.1.eureka
-
In eureka registry, show examples of successful service registration status, click the instance name to jump to the status-page-url page displays the status of the service instance. Shaped like:
// 20190615100528 // http://10.20.30.40:8888/info { }
-
Spring Boot Admin log in operation, the display normal health-check-url address: the form: http://10.20.30.40:10002/health.
-
In Spring Boot Admin application management page, successfully registered service overall state "UP", namely: on-line state.
1.2. The current exception service performance
- A class of service
- In eureka registry as usual, that is status-page-url normal.
- Spring Boot Admin log in operation, the display normal health-check-url.
- Always display "DOWN" in Spring Boot Admin page application management, service the whole state.
- B class service
- In eureka registry, status-page-url abnormalities, such as: HTTP: //x00001.prod.shunyi.beijing: 8888 / info.
- Spring Boot Admin log in operation, the display health-check-url abnormalities, such as: HTTP: //x00001.prod.shunyi.beijing: 8888 / Health.
- Always display "OFFLINE" in Spring Boot Admin page application management, service the whole state.
- Class C Service
- In eureka registry, status-page-url abnormalities, such as: http://172.17.0.2:8888/info.
- Spring Boot Admin log in operation, the display health-check-url abnormalities, such as: http://172.17.0.2:8888/health.
- Always display "OFFLINE" in Spring Boot Admin page application management, service the whole state.
Second, knowledge
Want to find out why the abnormal part eureka registered micro-service results, first figure out the logic status-page-url, health-check-url and the overall state of the services Spring Boot Admin.
Here, in turn be described.
2.1.Spring Boot Admin service overall status
Spring Boot Admin state service as a whole not just the state of the service itself, also includes state services this service depends.
Service overall status may be determined by the overall state:
- Service status itself
- eureka-client state
- eureka-server state
- State hard disk space
- State-dependent database
- A state-dependent ElasticSearch
- A state-dependent Redis
- 。。。
Services dependent on the overall state of the specific state which depends on what services are dependent pom.xml.
2.2.status-page-url和health-check-url
Overall Description
- eureka registry by status-page-url to query service status.
- Spring Boot Admin to check the service status through health-check-url.
- status-page-url and health-check-url may be explicitly configured, i.e.,
eureka.instance.status-page-url
andeureka.instance.health-check-url
. - In general, the need for explicit configuration, eureka-client form status-page-url and health-check-url automatic splicing according to the rules.
- Above three items are not explicitly configured.
Imprint
- Different versions of eureka-client has a different status-page-url and health-check-url automatic generation rules (in fact, this is an afterthought, is to solve the problems found in the process).
- A Class B Class services and service dependent version 1.5.6.RELEASE; class C service relies 1.5.8.RELEASE.
- Next, the two versions of the status-page-url and automatic generation rules of health-check-url is briefly described below.
- 1.5.6.RELEASE later chapters source generation rules interpretation, the source generation rules Interpretation of 1.5.8RELEASE may be reference.
1.5.6.RELEASE version status-page-url and health-check-url automatic generation rules
- Get the Profile prefer-ip-address, namely: whether a limited selection of ip-address.
- Obtains the address IpAddressConfiged profile ip-address configuration.
- Access to the machine (or container) and HostNameLocal IpAddressLocal through the Socket interfaces.
- IpAddressUesd setting will actually use the service for IpAddressLocal, service use HostNameUsed to HostNameLocal.
- If IpAddressConfiged is not empty, then cover IpAddressUesd is IpAddressConfiged.
- Automatically generated status-page-url and health-check-url, based on the following rules:
- status-page-url:https://{prefer-ip-address?IpAddressUesd:HostNameUsed}/info
- health-check-url:https://{prefer-ip-address?IpAddressUesd:HostNameUsed}/health
- Eureka configuration currently in practice, prefer-ip-address = true, ip-address = {pers.hanchao.ip}, therefore, the automatic generation rules converted to:
- status-page-url:https://{pers.hanchao.ip}/info
- health-check-url:https://{pers.hanchao.ip}/health
1.5.8.RELEASE version status-page-url and health-check-url automatic generation rules
- Get the Profile prefer-ip-address.
Obtains the address IpAddressConfiged profile ip-address configuration.- Access to the machine (or container) and HostNameLocal IpAddressLocal through the Socket interfaces.
- IpAddressUesd setting will actually use the service for IpAddressLocal, service use HostNameUsed to HostNameLocal.
If IpAddressConfiged is not empty, then cover IpAddressUesd is IpAddressConfiged.- Automatically generated status-page-url and health-check-url, based on the following rules:
- status-page-url:https://{prefer-ip-address?IpAddressUesd:HostNameUsed}/info
- health-check-url:https://{prefer-ip-address?IpAddressUesd:HostNameUsed}/health
- Eureka configuration currently in practice, prefer-ip-address = true, ip-address = {pers.hanchao.ip}, therefore, the automatic generation rules converted to:
- status-page-url:https://{IpAddressLocal}/info
- health-check-url:https://{IpAddressLocal}/health
- ip-address valid in this configuration the logic
Third, troubleshooting
3.1.A class microService
3.1.1. Analysis of reasons
Reference 2.1. Chapter, the investigation, A-type micro references redis service dependent, but did not use.
So redis connection status is not normal, that is, DOWN, resulting in the overall service status is DOWN.
3.1.2. Modify the description
Remove unwanted dependencies
<!-- 去除以下依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2.B class microService
3.2.1. Analysis of reasons
One reason: the dependence of the redis, but did not use. Reference: Section 3.1.1
Two reasons: eureka configuration is not complete
Referring to Section 2.2 of the 1.5.6.RELEASE
part, due to the lack prefer-ip-address ip-address and configuration, resulting in a final status-page-url and health-check-url follows:
- status-page-url:https://{HostNameLocal}/info
- health-check-url:https://{HostNameLocal}/health
- As mentioned at the beginning of the real-life example: HTTP: //x00001.prod.shunyi.beijing: 8888 / Health
3.2.2. Modify the description
- Modify application.properties, complement the service registry configuration (recommended reference section IV: The recommended configuration).
# 补充以下配置
eureka.instance.ip-address=${pers.hanchao.ip}
eureka.instance.prefer-ip-address=true
management.security.enabled=false
- Modify pom.xml, removing unwanted dependency.
<!-- 去除以下依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.3.C class microService
3.3.1. Analysis of reasons
After investigation, eureka configuration itself is no problem, as the problem is caused due to the different SpringBoot version.
Referring to Section 2.2 of the 1.5.8.RELEASE
section, because ip-address
an invalid configuration, resulting in a final status-page-url and health-check-url follows:
- status-page-url:https://{IpAddressLocal}/info
- health-check-url:https://{IpAddressLocal}/health
- ip-address valid in this configuration the logic
- {IpAddressLocal} in the unit was the unit address, the IP address was internal Docker Docker, shaped like: http://172.17.0.2:10002/health like.
3.3.2. Problem Solving
Modify bootstrap.yml, explicit configuration status-page-url and health-check-url (refer to chapter four recommendations: recommended).
eureka:
instance:
...
prefer-ip-address: true
# 显式配置 status-page-url和health-check-url
status-page-url: https://${pers.hanchao.ip}:${server.port:@@server.port@@}/info
health-check-url: https://${pers.hanchao.ip}:${server.port:@@server.port@@}/health
Four, eureka recommended configuration reference
- Note the difference between hump naming and naming of dashes.
- The following configuration is for reference, any inadequacies in the self-optimizing.
4.1.properties
eureka.client.enabled=true
# 推荐域名地址
eureka.client.service-url.defaultZone={eureka服务注册中心的注册地址}
eureka.instance.instance-id=${pers.hanchao.ip}:${spring.application.name}:${server.port}
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=${pers.hanchao.ip}
eureka.instance.lease-expiration-duration-in-seconds=15
eureka.instance.lease-renewal-interval-in-seconds=5
# 显式配置 status-page-url和health-check-url
eureka.instance.status-page-url=https://${pers.hanchao.ip}:${server.port:@@server.port@@}/info
eureka.instance.health-check-url=https://${pers.hanchao.ip}:${server.port:@@server.port@@}/health
management.security.enabled=false
4.2.yaml
eureka:
client:
enabled: true
service-url:
# 推荐域名地址
defaultZone: {eureka服务注册中心的注册地址}
instance:
instance-id: ${pers.hanchao.ip}:${spring.application.name}:${server.port}
prefer-ip-address: true
ip-address: ${pers.hanchao.ip}
lease-expiration-duration-in-seconds: 15
lease-renewal-interval-in-seconds: 5
# 显式配置 status-page-url和health-check-url
status-page-url: https://${pers.hanchao.ip}:${server.port:@@server.port@@}/info
health-check-url: https://${pers.hanchao.ip}:${server.port:@@server.port@@}/health
management:
security:
enabled: false
Five, 1.5.6.RELEASE version of the health-check-url automatically generate source code interpretation of rules
1. Obtain profile prefer-ip-address
-
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration#eurekaInstanceConfigBean:131
boolean preferIpAddress = Boolean.parseBoolean(eurekaPropertyResolver.getProperty("preferIpAddress"));
2. Get the address IpAddressConfiged profile ip-address configuration.
-
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration#eurekaInstanceConfigBean:132
String ipAddress = eurekaPropertyResolver.getProperty("ipAddress");
3. The access to the machine (or container) and HostNameLocal IpAddressLocal through the Socket interfaces.
-
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration#eurekaInstanceConfigBean:140
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
-
org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean#EurekaInstanceConfigBean(org.springframework.cloud.commons.util.InetUtils):286
public EurekaInstanceConfigBean(InetUtils inetUtils) { this.inetUtils = inetUtils; //通过Socket相关变成,获取host信息 this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo(); this.ipAddress = this.hostInfo.getIpAddress(); this.hostname = this.hostInfo.getHostname(); }
-
org.springframework.cloud.commons.util.InetUtils#findFirstNonLoopbackHostInfo:69
public HostInfo findFirstNonLoopbackHostInfo() { //通过Socket相关变成,获取host信息 InetAddress address = findFirstNonLoopbackAddress(); if (address != null) { return convertAddress(address); } HostInfo hostInfo = new HostInfo(); //将获取的hostName和ipAddress进行返还 hostInfo.setHostname(this.properties.getDefaultHostname()); hostInfo.setIpAddress(this.properties.getDefaultIpAddress()); return hostInfo; }
-
org.springframework.cloud.commons.util.InetUtils#findFirstNonLoopbackAddress:79
/** * 通过NetworkInterface获取InetAddress **/ public InetAddress findFirstNonLoopbackAddress() { InetAddress result = null; try { int lowest = Integer.MAX_VALUE; for (Enumeration<NetworkInterface> nics = NetworkInterface .getNetworkInterfaces(); nics.hasMoreElements();) { NetworkInterface ifc = nics.nextElement(); if (ifc.isUp()) { log.trace("Testing interface: " + ifc.getDisplayName()); if (ifc.getIndex() < lowest || result == null) { lowest = ifc.getIndex(); } else if (result != null) { continue; } // @formatter:off if (!ignoreInterface(ifc.getDisplayName())) { for (Enumeration<InetAddress> addrs = ifc .getInetAddresses(); addrs.hasMoreElements();) { InetAddress address = addrs.nextElement(); if (address instanceof Inet4Address && !address.isLoopbackAddress() && !ignoreAddress(address)) { log.trace("Found non-loopback interface: " + ifc.getDisplayName()); result = address; } } } // @formatter:on } } } catch (IOException ex) { log.error("Cannot get first non-loopback address", ex); } if (result != null) { return result; } try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { log.warn("Unable to retrieve localhost"); } return null; }
4. IpAddressUesd actually use the service is set to IpAddressLocal, service use HostNameUsed to HostNameLocal.
-
org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean#EurekaInstanceConfigBean(org.springframework.cloud.commons.util.InetUtils):287
this.ipAddress = this.hostInfo.getIpAddress();
-
org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean#EurekaInstanceConfigBean(org.springframework.cloud.commons.util.InetUtils):288
this.hostname = this.hostInfo.getHostname();
IpAddressConfiged 5. If not empty, the cover is IpAddressUesd IpAddressConfiged.
-
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration#eurekaInstanceConfigBean:146
if (StringUtils.hasText(ipAddress)) { instance.setIpAddress(ipAddress); }
6. automatically generated status-page-url and health-check-url, based on the following rules:
-
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration#eurekaInstanceConfigBean:171
instance.setStatusPageUrl(metadata.getStatusPageUrl());
-
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration#eurekaInstanceConfigBean:167
ManagementMetadata metadata = managementMetadataProvider.get(instance, serverPort, serverContextPath, managementContextPath, managementPort);
-
org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider#get:26
String healthCheckUrl = getHealthCheckUrl(instance, serverPort, serverContextPath, managementContextPath, managementPort, false);
-
org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider#getHealthCheckUrl:46
String healthCheckUrl = getUrl(instance, serverPort, serverContextPath, managementContextPath, managementPort, healthCheckUrlPath, isSecure);
-
org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider#getUrl:69
//关键在于参数 instance.getHostname() return constructValidUrl(scheme, instance.getHostname(), managementPort, managementContextPath, urlPath);
-
org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean#getHostname:276
public String getHostname() { return getHostName(false); }
7. prefer-ip-address ? IpAddressUesd : HostNameUsed
-
org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean#getHostName
@Override public String getHostName(boolean refresh) { if (refresh && !this.hostInfo.override) { this.ipAddress = this.hostInfo.getIpAddress(); this.hostname = this.hostInfo.getHostname(); } //prefer-ip-address ? IpAddressUesd : HostNameUsed return this.preferIpAddress ? this.ipAddress : this.hostname; }