1

Im trying to define a custom LoadBalancer by implementation the interface ReactorServiceInstanceLoadBalancer to replace the default load balancer defined by RoundRobinLoadBalancer.

But it doesn't work.

I found that the original bean defined in class 'LoadBalancerClientConfiguration' isn't instantiated when the application startup,but instantiated when 'LoadBalancerClientFactory.getInstance' is called, and the contructor is autowired with a bean of StandardEnvironment, while the bean defined in my configuration is instantiated when the application startup, and autowired with a bean of StandardReactiveWebEnvironment.

Very confused! My english is not so good.Thank you for reading the whole description! Here is my code below:

    `@Slf4j
public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    // ...detail omitted
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
public class CustomLoadBalancerClientConfiguration {
    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory, ServiceInstanceChooser serviceInstanceChooser) {
        String name = loadBalancerClientFactory.getName(environment);
        return new CustomLoadBalancer(serviceInstanceChooser, loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}
pigman
  • 86
  • 7

1 Answers1

2

A separate context, including the ReactorServiceInstanceLoadBalancer instance is created per requested serviceId. It is possible, to provide your own implementation, both default or for a specific service. Please see the documentation on how to provide custom configuration for Spring Cloud LoadBalancer.

OlgaMaciaszek
  • 3,662
  • 1
  • 28
  • 32
  • thanks for answering! i have tried the annotation of LoadBalancerClients and LoadBalancerClient before but it still doesn't work.the bean 'reactorServiceInstanceLoadBalancer' in my code is always immediately instantiated on startup.i know that the source code has a LoadBalancerClientFactory which expends NamedContextFactory and creates a bean of LoadBalancer for each serviceId,but it doesn't work when i write the same code .so i want to know how it works. – pigman Oct 23 '20 at 02:51
  • It's difficult to say without seeing more code. Could you create a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example), create a new GitHub issue in Spring Cloud Commons and link it there? – OlgaMaciaszek Oct 26 '20 at 11:46
  • I think most simple project,even like benchmark of spring-cloud-gateway, can reproduce my question. It's just the source code in spring-cloud-loadbalancer-2.2.4.RELEASE.jar,and i find it in debugging. see:org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration#reactorServiceInstanceLoadBalancer.how does it work?why is your bean just instantiated by calling the method LoadBalancerClientFactory#getInstance ,and the dependency of Environment is a instant of StandardWebEnvironment rather than a instant of StandardReactiveWebEnvironment as it is in my code above. – pigman Oct 27 '20 at 05:35
  • my project is a simple gateway depends on spring-boot-2.3.2.RELEASE and spring-cloud-Hoxton.SR7,with spring-cloud-starter-loadbalancer included. – pigman Oct 27 '20 at 05:40
  • You have written that you could not override the configuration, however, we and many community users do it regularly while working with the LoadBalancer, so a code sample would be helpful to understand why it's not working in your scenario. Most probably, as described in the linked docs, what might solve your issue is to use the `@LoadBalancerClient` annotation to pass the custom config instead of marking that class with `@Configuration`. – OlgaMaciaszek Oct 28 '20 at 16:29
  • Thank you very much for your patience! It works by using `@LoadBalancerClient` for one service,and I have used `@LoadBalancerClients` instead for a global definition.I made a mistake before so that it was mistaken for a wrong way. – pigman Oct 29 '20 at 02:18