I am using Spring reactor and WebClient for load balance purposes. I want to use the Request-based Sticky Session for LoadBalancer as follows:
Have service A that can invoke REST end points on service B or service C. Both B and C can have multiple instances of them running at a given time.
- I want to use the standard round robin balancer for service B.
- I want to use the request-based sticky session balancer for service C.
This is my code in the service A (that can invokes both service B and service C) through the WebClient. But it always ends up with round robin algorithm for service C. Can someone please help me to figure out what I am doing wrong or missed to do? I referred to the below link
and also looked into the below SO
Request-based Sticky Session configuration with Spring Cloud LoadBalancer
@Configuration
public class WebClientConfiguration {
@Bean
@LoadBalanced
@Qualifier("loadBalancedWebClientBuilder")
WebClient.Builder builder() {
return WebClient.builder();
}
@Bean
@Qualifier("webClientBuilder")
WebClient webClient(WebClient.Builder builder) {
return builder.build();
}
}
application.yml (I am not very sure where the sticky-session definition should be added; i.e. service A or service C and hence repeated the below in both the services)
spring:
application:
name: service-A
cloud:
loadbalancer:
ribbon:
enabled: 'false'
sticky-session:
instanceIdCookieName: sc-lb-instance-id
addServiceInstanceCookie: true
Code in the service A to invoke service C with request based sticky session. I have a different file that does the same for service B (without the sticky session but uses the same WebClient Builder). I know the service instance id that I want the WebClient to use to route the call.
@Component
public class ServiceCClient {
@Autowired
@Qualifier("loadBalancedWebClientBuilder")
private WebClient.Builder webClientBuilder;
public Mono<Void> triggerServiceCEndPoint(String paramA, String svcInstanceId) {
return webClientBuilder.baseUrl("http://service-C").build()
.post().uri(uriBuilder -> uriBuilder.path("/v1/example/end/point")
.queryParam("param-a",paramA).build())
.headers(httpHeaders -> {
httpHeaders.set("sc-lb-instance-id",svcInstanceId);
})
.cookie("sc-lb-instance-id", svcInstanceId)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Void.class);
}
}