spring-cloudspring-cloud-loadbalancer

Request-based Sticky Session configuration with Spring Cloud LoadBalancer


I have the following configuration for request-based sticky session using Spring Cloud LoadBalancer

spring:
  cloud:
    discovery.client.simple.instances:
      say-hello:
        - instanceId: say-hello1
          uri: http://localhost:8080
        - instanceId: say-hello2
          uri: http://localhost:8081

    loadbalancer:
      configurations: request-based-sticky-session
      sticky-session:
        add-service-instance-cookie: true

server.port:9090

the following call:

$ http :9090/hi 'Cookie:sc-lb-instance-id=say-hello1'

should go only to the say-hello1 instance based on the Request-based Sticky Session for LoadBalancer but instead is using round robin load balancing.

What do I miss here?

Here is the source code to try it: https://github.com/altfatterz/client-side-loadbalancing


Solution

  • There are 2 things to consider here:

    1. In the sample, the cookie has to be passed on to the actual load-balanced request, for example like so:

      @GetMapping("/hi")
      public String hi(@RequestParam(value = "name", defaultValue = "Mary") String name) {
       logger.info("Accessing /hi endpoint");
       HttpHeaders headers = new HttpHeaders();
       headers.set("Cookie", "sc-lb-instance-id=say-hello1");
      
       HttpEntity entity = new HttpEntity(headers);
       ResponseEntity<String> greeting = restTemplate.exchange("http://say-hello/greeting", HttpMethod.GET, entity, String.class, new HashMap<>());
       return greeting + " " + name;
      }
      
    2. This feature is only supported for WebClient-backed load-balancing. It was not properly documented. I have documented it here. I have also created a GitHub issue for adding the non-reactive implementation, however, the decision to implement it will be dependant on larger community interest.