Spring Boot Ribbon负载均衡配置的坑(避免被ComponentScan扫描)

配置

Spring Boot Ribbon负载均衡配置很简单,网上一搜类似下面:

@Configuration
public class LoadBalanceConfiguration {

    @Bean
    public IRule rule() {
        return new WeightedResponseTimeRule();
    }
}

在Ribbon的文档中有这样一段话:

The FooConfiguration has to be @Configuration but take care that it is not in a @ComponentScan for the main application context, otherwise it will be shared by all the @RibbonClients. If you use @ComponentScan (or @SpringBootApplication) you need to take steps to avoid it being included (for instance put it in a separate, non-overlapping package, or specify the packages to scan explicitly in the @ComponentScan).

大体意思是对于Ribbon的配置必须用@Configuration注解标识,并且不能被@Component注解或者@SpringBootApplication(因为里面包含了@Component)扫描到。因为如果被@ComponetScan扫描到会导致所有的RibbonClient都去共享这个配置。

楼主在使用Spring Cloud Gateway网关的过程中因为这样自定义了负载均衡策略,但是出现:

访问A服务:A/foo再去访问B服务B/bar, 这个时候转头回来再访问A/foo的时候会出现404.

通过debug发现在路由到指定的服务之后,使用Ribbon去做负载均衡,但是此时返回的负载均衡ILoadBalancer中锁包含的IRule(负载均衡策略, 其中可以通过setLoadBalancer设置负载均衡器)实际上是上一个服务(B服务)的负载均衡器。

 

解决

按照上面英文描述的思路,方案如下:

@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(basePackages = "com.foo.bar", excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = LoadBalanceConfiguration.class)})
public class FooGatewayApplication {

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

 

关于具体的负载均衡策略配置,以及@ComponentScan详解请自行百度。

你可能感兴趣的:(Spring,Boot,Spring)