Eureka Client Instance status DOWN - SpringCloud Eureka 实例状态为DOWN时如何排查问题

本文介绍当Spring Cloud Eureka实例状态显示为DOWN时的排查方法。主要从发现问题、产生原因及解决步骤等方面进行详细阐述。

Eureka Client Instance status DOWN - SpringCloud Eureka 实例状态为DOWN时如何排查问题

发现问题

启动spring boot application注册euraka clienteureka server后,可以在eureka.server.ip:port看到对应的实例列表,但是实例前面有一个红色的DOWN:
这里写图片描述
如果用ip去访问这个服务的REST接口,是完全没有问题的;但是如果用RestTemplateFeignClient通过applicationName访问就会失败。

产生原因

注册到eureka server的服务,如果开启了健康检查,spring boot程序会隔一小段时间就检查一下配置的一些外部资源是否可用,比如各种数据源是否能联通,如果任意一个配置无法正常连通,就会向eureka server推送消息让该实例下线。这相当于是一个hearbeat,检查各个实例是否能正常使用。当然自己也可以自己实现HealthCheckHandler来个性化健康检测,甚至给一个REST接口更改getStatus()返回值,以实现主动上下线的操作,具体可以参考这里:springcloud-eureka集群-健康检测

其中,打开健康检测的功能需要有以下配置:
pom中引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.properties需要打开健康检测:

eureka.client.healthcheck.enabled = true

启动应用后,就可以通过访问:
${spring.cloud.client.ipAddress}:${server.port}[/server.contextPath]/health
来查看健康情况,正常时返回:

{"details":{},"status":{"code":"UP","description":"Spring Cloud Eureka Discovery Client"}}

异常时返回:

{"details":{},"status":{"code":"DOWN","description":""}}

Eureka服务中心的状态就根据这些数据来更新的。

解决问题

找到问题的源头就可以很快解决了。
首先,访问一下
${spring.cloud.client.ipAddress}:${server.port}[/server.contextPath]/health(如果状态是DOWN,健康检测机制会多次重试确保真的挂了,所以可能会等待稍长的时间才会返回结果),如果这里是真的DOWN,那么就可以断定是某个资源不可用导致的,一般日志里都有打印错误,比如MySQL挂了,日志就会不停地打印:

...
[2018-06-14 20:26:16] [http-nio-8089-exec-2] [ERROR] [com.alibaba.druid.filter.logging.Log4jFilter:152] {conn-10002, stmt-20007} execute error. SELECT 1
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
...

如果无法访问
${spring.cloud.client.ipAddress}:${server.port}[/server.contextPath]/health这个接口,等到烟火清凉也没有返回,而且应用并未配置任何外部资源、或者所有外部资源确认可以访问,说明这个应用思想出问题了,这次我遇到的就是这个情况。这时要特别留意日志里的WARN级别信息,这些WARN相当重要,这次问题遇到了8WARN

[2018-06-14 19:51:54] [main] [WARN] [org.mybatis.spring.mapper.ClassPathMapperScanner:166] No MyBatis mapper was found in '[com.xx.xx.core, com.xx.xx]' package. Please check your configuration.
[2018-06-14 19:51:55] [main] [WARN] [org.mybatis.spring.mapper.ClassPathMapperScanner:166] No MyBatis mapper was found in '[com.xx.xx.**.mapper]' package. Please check your configuration.
[2018-06-14 19:51:55] [main] [WARN] [org.springframework.context.annotation.ConfigurationClassPostProcessor:373] Cannot enhance @Configuration bean definition 'myBatisMapperScannerConfig' since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.
[2018-06-14 19:52:05] [main] [WARN] [com.netflix.config.sources.URLConfigurationSource:121] No URLs will be polled as dynamic configuration sources.
[2018-06-14 19:52:05] [main] [WARN] [com.netflix.config.sources.URLConfigurationSource:121] No URLs will be polled as dynamic configuration sources.
[2018-06-14 19:52:05] [main] [WARN] [org.springframework.boot.autoconfigure.thymeleaf.AbstractTemplateResolverConfiguration:60] Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
[2018-06-14 19:52:09] [DiscoveryClient-InstanceInfoReplicator-0] [WARN] [com.netflix.discovery.DiscoveryClient$3:1277] Saw local status change event StatusChangeEvent [timestamp=1528977129378, current=DOWN, previous=UP]
[2018-06-14 19:52:09] [DiscoveryClient-InstanceInfoReplicator-0] [WARN] [com.netflix.discovery.InstanceInfoReplicator:93] Ignoring onDemand update due to rate limiter

前两个WARN基本就可以定位到问题了,因为当前应用没有任何外部资源,提示里不存在的两个包路径也没有在任何地方有配置,这就说明一定是父项目或者依赖项目有导致DOWN的配置,果不其然,依赖了一个包,里面有数据库配置,而且连不上……exclusion掉对应的包,一切正常了。

/health接口无法访问的原因可能也是因为重试,资源的具体配置是在父项目或者依赖项目中,可能无法正常请求或返回,导致一直卡住(不确定是这个原因)。

后面有两个WARN提示了状态变更,如果想看所有动作日志,还可以在logback中打开DEBUG,就会清楚地看到向eureka server PUT状态的HTTP请求详情。

事后总结

解决问题的时候走了一些弯路,包括到sping cloud github上找issues,以为是spring bootspring cloud版本冲突,以为是父项目和子项目的版本冲突等等,其实就是有外部资源检查不可用,主要是访问/health接口失败断了节奏。

<think>我们正在解决Eureka服务器中应用状态DOWN,导致服务无法调用的问题。用户提到一个具体的服务名"ehrmms-main-service"处于DOWN状态且正在注销(unregistering),因此无法被调用。根据Eureka的工作原理,服务实例会定期向Eureka服务器发送心跳来维持其注册状态。如果Eureka服务器在一段间内没有收到某个实例的心跳,它会将该实例状态标记为DOWN,然后开始注销过程。这可能是由于以下原因之一:1.服务实例本身崩溃或停止运行。2.网络问题导致心跳无法到达Eureka服务器。3.服务实例过载,无法及发送心跳。4.Eureka服务器配置问题,如续约阈值设置过低。解决步骤:1.**检查服务实例状态**:首先确认"ehrmms-main-service"实例是否正常运行。可以查看该实例的日志,确认它是否在运行并且能够发送心跳。2.**检查网络连接**:确保从服务实例Eureka服务器的网络连接是正常的,没有防火墙阻止心跳请求(默认情况下,心跳使用HTTP请求)。3.**检查Eureka配置**:-在服务实例(客户端)配置中,检查以下属性(通常在application.properties或application.yml中):```properties#心跳间隔,默认30秒eureka.instance.lease-renewal-interval-in-seconds=30#没有心跳后的等待间,默认90秒eureka.instance.lease-expiration-duration-in-seconds=90```-Eureka服务器配置中,检查是否配置了自我保护模式(默认开启)。在自我保护模式下,Eureka不会注销没有心跳的服务实例,但可能会标记为DOWN。如果问题发生在自我保护模式下,可能是正常的保护行为。但用户明确提到正在注销(unregistering),所以可能是自我保护模式关闭了。```properties#是否开启自我保护模式,默认trueeureka.server.enable-self-preservation=true```4.**检查Eureka服务器日志**:查看Eureka服务器的日志,看是否有关于该服务实例的异常记录,例如拒绝心跳请求等。5.**强制刷新**:如果确定服务实例是健康的,可以尝试在Eureka服务器上强制刷新缓存(例如,通过重启Eureka服务器,或者调用Eureka的RESTAPI进行刷新)。如果服务实例确实已经停止,那么需要重启该服务实例,并确保它能够成功注册到Eureka。相关问题:1.如何配置Eureka的自我保护模式以避免服务实例被错误注销?2.当服务实例健康但Eureka标记为DOWN,如何手动设置服务实例状态为UP?3.Eureka服务发现机制中,客户端如何缓存服务列表?当服务状态变化,客户端如何更新?注意:上述引用内容与当前问题关联性不大,因此我们主要基于Eureka的常见问题解决思路进行回答。</think>### Eureka服务器应用状态DOWN导致无法调用的问题解决 您遇到的Eureka服务器中`ehrmms-main-service`状态为`DOWN`且正在注销(unregistering),导致服务无法调用的问题,通常由以下原因及解决方案组成: --- #### **原因分析与解决方案** 1. **服务心跳丢失 (最常见)** - **原因**:服务实例未能及发送心跳到Eureka服务器(默认30秒一次),超过租约到期间(默认90秒)后被标记为`DOWN` - **解决**: ✅ 检查服务实例日志,确认是否正常发送心跳: ```java // 查看心跳日志关键词 com.netflix.discovery.DiscoveryClient : Renewing lease... ``` ✅ 调整客户端配置(`application.yml`): ```yaml eureka: instance: lease-renewal-interval-in-seconds: 15 # 心跳间隔缩短至15秒 lease-expiration-duration-in-seconds: 45 # 租约超缩短至45秒 ``` 2. **网络分区问题** - **原因**:服务实例Eureka服务器间网络不稳定,导致心跳包丢失[^1] - **解决**: ✅ 使用`telnet eureka-host 8761`测试网络连通性 ✅ 在服务实例侧添加重试机制: ```yaml spring: cloud: loadbalancer: retry: enabled: true ``` 3. **服务健康检查失败** - **原因**:Eureka通过`/actuator/health`端点监控服务状态,若返回`DOWN`则同步状态 - **解决**: ✅ 检查服务健康端点:`curl http://ehrmms-main-service:port/actuator/health` ✅ 修复健康检查依赖(如数据库连接、磁盘空间等) 4. **自我保护模式干扰** - **原因**:Eureka Server进入自我保护模式(日志提示`SELF PRESERVATION MODE`)拒绝注销实例 - **解决**: ✅ 临关闭自我保护(生产环境慎用): ```yaml # Eureka Server配置 eureka: server: enable-self-preservation: false ``` 5. **强制状态刷新** - **手动触发**:通过Eureka API强制更新状态: ```bash # 1. 注销异常实例 curl -X DELETE http://eureka-server:8761/eureka/apps/EHRMMS-MAIN-SERVICE/instance-id # 2. 服务实例重新注册 curl -X POST http://eureka-server:8761/eureka/apps/EHRMMS-MAIN-SERVICE -H "Content-Type: application/json" -d '{"instance": { ... }}' # 实例配置信息 ``` --- #### **预防措施** 1. **配置优化** ```yaml # 客户端配置 eureka: client: healthcheck: enabled: true # 启用健康检查 registry-fetch-interval-seconds: 10 # 客户端刷新注册表间隔 ``` 2. **增加冗余** - 部署多个Eureka Server节点组成集群 - 使用`spring-cloud-starter-netflix-eureka-server`集群配置: ```yaml # 集群节点配置示例 eureka: client: serviceUrl: defaultZone: http://peer1:8761/eureka/,http://peer2:8761/eureka/ ``` 3. **日志监控** - 监控关键日志条目: - `Lease expired or disabled...` - `Cancelled lease...` - 配置告警规则:当`DOWN`状态实例持续超过5分钟触发告警 > **关键点**:服务状态转换流程: > `UP → 心跳丢失 → 标记DOWN → 等待90秒 → 触发UNREGISTERING → 从注册表移除` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值