我在 Spring 微服务项目中使用 Spring Cloud 负载均衡器作为客户端负载均衡器。我知道默认情况下 Spring 负载均衡器使用循环策略。但对于我的用例来说,
Least connections
策略是最适合的。处理最少连接数的实例将请求路由到它。在深入研究文档后,我发现 @LoadBalancerClient
注释可以让您了解路由算法。
所以,我这样做了:
@Configuration
@LoadBalancerClient(configuration = BalancerConfig.class)
public class RestConfig {
@Bean
@LoadBalanced
RestTemplate restClient(RestTemplateBuilder builder) {
return builder.build();
}
}
对于 BalancerConfig.java 类,我有:
@Configuration
public class BalancerConfig {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
// currently selects an instance randomly of a given service.
// but I want to switch it to use the instance that is currently having least
// traffic
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
请告诉我 Spring 应用程序网关是否可以实现?
如果您希望所有客户端都使用自定义策略,您只需要定义一个ReactorLoadBalancer bean,如下所示
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
但是如果你想为每个客户定制不同的策略,你需要这样做
public class RestConfig {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
配置两条路由
spring.cloud.gateway.routes[0].id=web
spring.cloud.gateway.routes[0].uri=lb://web
spring.cloud.gateway.routes[0].predicates[0]=Path=/web/**
spring.cloud.gateway.routes[1].id=reactive-web
spring.cloud.gateway.routes[1].uri=lb://reactive-web
spring.cloud.gateway.routes[1].predicates[0]=Path=/reactive/**
运行 GateWay 应用程序
@LoadBalancerClient(value = "reactive-web",configuration = RestConfig .class)
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
}
这样第一条路由使用了RoundRobinLoadBalancer,第二条路由使用了RandomLoadBalancer。