You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud LoadBalancer结合Feign客户端负载均衡配置问题

问题:Spring Boot + Spring Cloud LoadBalancer 实现Feign客户端负载均衡配置问题

环境

  • Spring Boot v3.2.6
  • Spring Cloud v2023.0.1
  • 目标:结合Spring Cloud LoadBalancer实现Feign客户端负载均衡

已配置代码

Feign客户端

@FeignClient(value = "eisec2")
public interface Eisec2Client {

    @GetMapping(path = "base1/path/{number}", consumes = MediaType.APPLICATION_XML_VALUE)
    String getCaller(@PathVariable("number") String cli);

    @RequestMapping(path = "status", method = RequestMethod.GET)
    CallDetails getStatus();
}

负载均衡配置类

@RequiredArgsConstructor
@EnableFeignClients("com.frequentis.isec_server.client")
@LoadBalancerClient(value = "eisec2", configuration = LoadBalancerConfiguration.class)
public class FeignEisec2InstanceBalancingConfiguration {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

LoadBalancerConfiguration

public class LoadBalancerConfiguration {

    @Bean // <-- 注释该Bean时程序"可用"
    public ServiceInstanceListSupplier instanceSupplier(ConfigurableApplicationContext context, DiscoveryClient discoveryClient) {
        return ServiceInstanceListSupplier.builder()
                .withHints()
                .withBlockingDiscoveryClient()
                .withBlockingHealthChecks(new RestTemplate())
                .build(context);
    }

    @Bean
    ReactorLoadBalancer<ServiceInstance> rrLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        final RoundRobinLoadBalancer roundRobinLoadBalancer = new RoundRobinLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(
                        name,
                        ServiceInstanceListSupplier.class),
                name);
        return roundRobinLoadBalancer;
    }
}

application.properties配置

spring.application.name=balanced-server
spring.cloud.loadbalancer.enabled=true
spring.cloud.discovery.client.simple.instances.eisec2[1].uri=http://localhost:6090/eisec/1
spring.cloud.discovery.client.simple.instances.eisec2[0].uri=http://10.16.207.***:6090/eisec/1
spring.liquibase.enabled=false
server.http2.enabled=false

遇到的问题

  • 注释ServiceInstanceListSupplier的@Bean时,程序仅调用配置中第一个服务实例,无法实现负载均衡;
  • 取消注释该Bean时,会出现「No servers available for service: eisec2」警告,日志输出重复;
  • 尝试非阻塞式ServiceInstanceListSupplier时,报错缺少ReactiveDiscoveryClient Bean,但项目不想引入Reactor依赖。

已确认DiscoveryClient能正确读取服务实例配置,求正确配置实现Feign客户端负载均衡。


解决方案

1. 修复ServiceInstanceListSupplier配置

当前配置的核心问题在于健康检查逻辑和实例提供者的构建方式:

  • 默认的withBlockingHealthChecks会检查/actuator/health端点,如果目标服务未暴露该端点,实例会被标记为不可用,导致「No servers available」警告;
  • 链式调用未正确传入DiscoveryClient实例,导致实例加载异常。

修改LoadBalancerConfiguration中的instanceSupplier方法:

方案1:移除健康检查(若不需要)

@Bean
public ServiceInstanceListSupplier instanceSupplier(ConfigurableApplicationContext context, DiscoveryClient discoveryClient) {
    return ServiceInstanceListSupplier.builder()
            .withBlockingDiscoveryClient(discoveryClient)
            .build(context);
}

方案2:自定义健康检查路径(若需要健康校验)

如果要保留健康检查,需指定目标服务的健康检查接口(比如你的/status接口):

@Bean
public ServiceInstanceListSupplier instanceSupplier(ConfigurableApplicationContext context, DiscoveryClient discoveryClient) {
    RestTemplate restTemplate = new RestTemplate();
    // 基于阻塞式DiscoveryClient构建实例提供者
    DiscoveryClientServiceInstanceListSupplier baseSupplier = 
        new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment());
    // 绑定健康检查逻辑,指定你的服务健康检查路径
    HealthCheckServiceInstanceListSupplier healthCheckSupplier = 
        new HealthCheckServiceInstanceListSupplier(baseSupplier, restTemplate);
    healthCheckSupplier.setHealthCheckUrl("/status");
    return healthCheckSupplier;
}

2. 确保轮询负载均衡器生效

你的rrLoadBalancer Bean配置是正确的,只要ServiceInstanceListSupplier能正常返回可用实例,轮询策略就会自动生效。之前注释ServiceInstanceListSupplier时只调用第一个实例,是因为默认实例提供者未正确触发轮询逻辑。

3. 清理冗余配置(可选)

FeignEisec2InstanceBalancingConfiguration中定义的@LoadBalanced RestTemplate,若未被其他业务逻辑使用,可直接移除,避免对Feign客户端的负载均衡逻辑造成干扰。

4. 验证配置

修改完成后,启动项目调用Feign接口,观察日志是否轮询调用两个实例。可开启调试日志查看实例选择过程:

logging.level.org.springframework.cloud.loadbalancer=DEBUG

关键注意事项

  • 确认目标服务实例的uri配置正确,末尾不要添加多余路径(Feign接口路径会自动拼接在uri之后);
  • 若使用健康检查,必须保证目标服务的健康检查接口能返回200状态码,否则实例会被排除在可用列表之外。

内容的提问来源于stack exchange,提问作者greengold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:41:16