问题描述


Spring cloud微服务项目,在刚刚运行的几秒内访问客户端方法:@RequestMapping(value = "/hellostudent",method = RequestMethod.GET)

页面报错

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Apr 21 19:56:46 CST 2025 There was an unexpected error (type=Not Found, status=404).

控制台报错

-04-21T19:57:06.280+08:00 WARN 2544 --- [eureka-feign-client] [nio-8764-exec-1] o.s.c.l.core.RoundRobinLoadBalancer : No servers available for service: eureka-provider 2025-04-21T19:57:06.280+08:00 WARN 2544 --- [eureka-feign-client] [nio-8764-exec-1] .s.c.o.l.FeignBlockingLoadBalancerClient : Load balancer does not contain an instance for the service eureka-provider 2025-04-21T19:57:06.281+08:00 ERROR 2544 --- [eureka-feign-client] [nio-8764-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: feign.FeignException$ServiceUnavailable: [503] during [GET] to [http://eureka-provider/getname?name=zhang] [FeignService#hello(String)]: [Load balancer does not contain an instance for the service eureka-provider]] with root cause

问题原因

当提供者(eureka-provider)一启动,它就会向 Eureka 注册自己的信息;消费者(eureka-feign-client)也会向 Eureka 注册,然后开始定时拉取注册表信息(也叫 registry cache),这个过程并不是立刻完成的。

  • Eureka Client(也就是消费者)每隔 30 秒 拉取一次注册表(可配置 eureka.client.registry-fetch-interval-seconds)。

  • 所以即便服务已经 UP,但消费者 可能还没来得及拉取到最新的提供者列表,就已经去调用了,这时就会报错:

提供者注册时,Eureka 是延迟让服务进入可用状态的,它默认要等待 30 秒的 lease renewal(心跳),也就是:

  • 提供者向 Eureka 注册时,会声明自己每隔几秒发送一个心跳(默认 30 秒一次);

  • Eureka 会等一两个心跳周期之后,才会认为这个服务是“稳定的”,可提供服务

  • 所以消费者在启动初期拉到的注册表中,可能不包含这个还未“稳定”的服务实例

解决方法

让Eureka 客户端的立即获取注册表

eureka:
  client:
    fetch-registry: true
    registry-fetch-interval-seconds: 5  # 默认是30秒,调低一点加快拉取

这里我直接改成1秒了,快一点

让提供者更快进入服务状态

在提供者的 application.yml 里添加以下配置(尤其是第一个):

eureka:
  instance:
    lease-renewal-interval-in-seconds: 5      # 心跳间隔时间,默认是30秒
    lease-expiration-duration-in-seconds: 10  # 服务超时下线时间,默认90秒
  client:
    register-with-eureka: true
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:7000/eureka/

这两项的含义是:

  • 5秒打一次“心跳”

  • Eureka认为超过10秒没心跳就下线服务

这样 Eureka 在更短的时间内就能把服务提供者标记为“可用”状态

 

Logo

一站式 AI 云服务平台

更多推荐