Spring微服务中已注册的应用A无法被正常调用问题求助
问题描述
应用A已成功注册至Eureka,在Eureka所在虚拟机中可正常查看A的状态(状态为UP),但Spring微服务调用A时却提示「target application is not online」。
已知信息
- 该微服务集群在其他环境运行完全正常
- 访问
~/eureka/apps接口能清晰看到Service A的注册信息 - 在Eureka所在机器上调用A的
~/health接口,返回结果为UP - 调用
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient#choose(java.lang.String)方法返回null,触发了自定义报错「target application is not online」,相关代码片段:instance = loadBalancer.choose(applicationName); - 重启Eureka后,微服务能临时正常访问A,但很快会再次出现相同错误
- 依赖版本:
spring-cloud-netflix-eureka-client-2.2.8.RELEASE.jar
排查与解决方案
针对这类Ribbon无法正确获取Eureka实例的问题,可从以下几个方向排查:
1. 调整Ribbon服务列表刷新间隔
Ribbon默认会缓存Eureka的服务实例列表,默认刷新间隔是30秒,当Eureka的实例状态变更后,Ribbon缓存可能没及时同步。
- 解决办法:在调用方微服务的配置文件中添加:
将刷新间隔改为2秒,加快缓存与Eureka的同步速度。ribbon.ServerListRefreshInterval=2000
2. 修复Eureka实例状态同步问题
虽然Eureka控制台显示实例UP,但调用方的Eureka Client可能没正确拉取到实例的健康状态,大概率和Eureka的响应缓存或Client健康检查配置有关。
- 解决步骤:
- 在Eureka Server的配置文件中关闭只读响应缓存并缩短更新间隔:
eureka.server.response-cache-update-interval-ms=5000 eureka.server.use-read-only-response-cache=false - 在调用方微服务开启Eureka健康检查同步:
eureka.client.healthcheck.enabled=true
- 在Eureka Server的配置文件中关闭只读响应缓存并缩短更新间隔:
3. 检查Ribbon负载均衡规则
部分负载均衡规则(比如AvailabilityFilteringRule)会自动过滤标记为故障的实例,如果Ribbon内部的故障判定逻辑异常,可能误把正常实例排除在外。
- 解决办法:
- 临时切换为最基础的轮询规则,验证是否是规则问题,在调用方配置文件添加:
# 替换[ServiceA-Name]为实际的应用A名称 [ServiceA-Name].ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule - 如果用了Hystrix,检查断路器配置,确认没有误触发熔断导致实例被标记为不可用。
- 临时切换为最基础的轮询规则,验证是否是规则问题,在调用方配置文件添加:
4. 排查网络连通性问题
虽然Eureka所在机器能访问A的健康接口,但调用方微服务和A之间可能存在隐性网络问题,比如防火墙拦截、端口映射错误、网络波动等,导致Ribbon尝试连接时失败,进而标记实例为不可用。
- 解决步骤:
- 在调用方机器上用
telnet [A的IP] [A的端口]或curl http://[A的IP]:[A的端口]/health验证连通性 - 检查调用方与A所在机器的防火墙、安全组规则,确保通信端口开放
- 确认服务A注册到Eureka的IP/端口是调用方可达的(避免使用虚拟机内部IP,改用外部可访问的IP)
- 在调用方机器上用
内容的提问来源于stack exchange,提问作者ShawnChen
相关产品推荐
相关产品推荐

