springspring-bootspring-cloudspring-cloud-feignspring-cloud-loadbalancer

Spring Cloud 2022 Load Balancer Compatibility with Feign Client


We are having an issue with our custom load balancing after upgrading our project to spring boot 3.1.3. We are using feign clients to connect to our apps using spring's load balancing and open feign libraries. The following classes are what we are using to setup our feign load balancing.

@LoadBalancerClient(name = "example-service", configuration = CustomLoadBalancerConfiguration.class)
@FeignClient(name = "example-service", configuration = CustomRequestInterceptorConfiguration.class)
public interface ExampleServiceClient
{
}
@Slf4j
public class CustomLoadBalancerConfiguration
{
    @Bean
    public ReactorServiceInstanceLoadBalancer customLoadBalancer()
    {
       //logic here
    }
}

The issue we are encountering is that we notice that the CustomRequestInterceptorConfiguration beans get instantiated in the @FeignClient annotation, but we do not see the CustomLoadBalancerConfiguration bean get instantiated in the @LoadBalancerClient annotation. We did do some investigation and found that the bean in CustomLoadBalancerConfiguration gets instantiated when the feign client is called at runtime for the first time in the previous version that we were using of spring boot and spring cloud. With the new version, this custom load balancing bean is no longer being instantiated so our custom load balancing rules are not being executed but rather spring's default round robin algorithm. Does anyone know if the new spring cloud version deprecated the @LoadBalancerClient annotation being used with feign clients? We checked the spring cloud 2022 release notes here https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2022.0-Release-Notes and found this statement: "AsyncRestTemplate has been removed in Spring Framework 6, therefore auto-configuration for LoadBalancer has been removed". Is this their way of trying to push everyone to use load balanced web clients now or are we just missing a configuration in this newer version of spring?

Our dependencies are as follows:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-dependencies</artifactId>
  <version>2022.0.3</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  <version>4.0.3</version>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
  <version>4.0.3</version>
</dependency>

Solution

  • Have you tried moving the @LoadBalancerClient annotation to the main application class like so?

    @SpringBootApplication
    @LoadBalancerClient(value = "my-service", configuration = CustomConfig.class)
    public class MySpringApplication
    {
       ...
    }
    

    And if you have multiple clients you can do the following.

    @LoadBalancerClients(value = {
       @LoadBalancerClient(value = "my-service", configuration = CustomConfig.class),
       @LoadBalancerClient(value = "my-other-service", configuration = CustomConfig.class)
    })
    

    I was having similar issues and that seemed to resolve it. I believe the problem stems from having the annotation on an interface as opposed to a class. Although I'm not entirely sure why that stopped working with this update.