负载均衡器没有可供客户端使用的服务器:会议

Load balancer does not have available server for client: meeting

当我尝试通过 Zuul 网关访问服务 meeting 时,Zuul 无法将请求转发到相应的服务。以下是我面临的错误:

  1. nettflix.zuul.exception.ZuulException: Forwarding error
  2. Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: meeting

让我分享一下application.yml服务,eureka和zuul网关。

EurekaClient: Application.yml

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
    lease-renewal-interval-in-seconds: 300
  client:
    register-with-eureka: false
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

ZuulGateWay: application.yml

server:
  port: 8085

spring:
  application:
    name: gatekeeper


zuul:
  routes:
    meeting: /meeting/**
    serviceId: meeting

ribbon:
  eureka:
    enabled: false

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

ZuulGateWay: SpringBootApplication

package com.sagarp.gatekeeper;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class MeetingApplication {

    public static void main(String[] args) {
        SpringApplication.run(MeetingApplication.class, args);
    }
}

我的服务class(会议):Application.yml

server:
  port: 0
spring:
  application:
    name: meeting
  datasource:
    url: jdbc:mysql://localhost:3306/sagarp?useSSL=false
    username: myUserName
    password: myPassWord
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate:
     ddl-auto: update

eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    lease-renewal-interval-in-seconds: 5

我的服务class(会议):SpringBootApplication

package com.sagarp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class MeetingApplication {

    public static void main(String[] args) {
        SpringApplication.run(MeetingApplication.class, args);
    }
}

如您所见,配置确保我的所有服务都被eureka客户端发现。

在eureka console中,我验证了一样,zuul gatewaymy service(meeting)都是可见的。

为了更好地查看,您可以访问我的 git 存储库。 https://github.com/sagar-patro/demo-microservices

任何帮助将不胜感激

简答

ribbon:
  eureka:
    enabled: false

Spring Cloud Netflix Zuul 使用 Netflix 的 Ribbon 执行 客户端负载平衡,默认情况下,Ribbon 将使用 Netflix Eureka 进行 服务发现 。您正在跳过 服务发现 ,因此您已将 ribbon.eureka.enabled 设置为 false。由于Ribbon现在不能使用Eureka查找服务,所以必须为meeting服务指定一个url :

meeting:
  ribbon:
    listOfServers: localhost:8080

扩展答案

我再给你说清楚

您当前在 gatekeeper 项目中使用的依赖项 org.springframework.cloud:spring-cloud-starter-netflix-zuul 具有多个编译依赖项:

com.netflix.zuul:zuul-core
org.springframework.boot:spring-boot-starter-web        
org.springframework.boot:spring-boot-starter-actuator       
org.springframework.cloud:spring-cloud-netflix-zuul
org.springframework.cloud:spring-cloud-starter      
org.springframework.cloud:pring-cloud-starter-netflix-hystrix
org.springframework.cloud:spring-cloud-starter-netflix-ribbon
org.springframework.cloud:spring-cloud-starter-netflix-archaius

如你所见,它构成了围绕com.netflix.zuul:zuul-core模块聚集的许多组件(包括用于实例发现的Eureka和用于路由的Ribbon):

当您启动 gatekeeper 应用程序时,将应用默认的 ZuulProxyAutoConfiguration 配置。它导入功能区配置 类:

@Configuration
@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class,
        RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class,
        RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class,
        HttpClientConfiguration.class })
@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class)
public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration { ... }

HttpClientRibbonConfiguration 又会初始化 RibbonLoadBalancingHttpClient,它会导致您看到的错误消息。

默认情况下 RibbonLoadBalancingHttpClient 使用来自 com.netflix.ribbon:ribbon-loadbalancer 包的 ZoneAwareLoadBalancer

By default Zuul load balances using the ZoneAwareLoadBalancer from Ribbon. The algorithm is a round robin of the instances available in discovery, with availability zone success tracking for resiliency. The load balancer will keep stats for each zone and will drop a zone if the failure rates are above a configurable threshold.

If you want to use your own custom load balancer you can set the NFLoadBalancerClassName property for that Ribbon client namespace or override the getLoadBalancerClass() method in the DefaultClientChannelManager. Note that your class should extend DynamicServerListLoadBalancer.

说明Zuul将路由和负载均衡工作委托给Ribbon组件,证明你在gatekeeper项目中确实使用了Ribbon

除非你选择不同的负载均衡器,否则你应该选择我原来的答案。
希望对你有所帮助。