Search code examples
haproxy

haproxy stick to group of backend servers


So I am struggling to find the correct config for my haproxy:

I have Ruby on Rails web application which is served by two physical hosts, each having 3 workers. The two hosts each have a database, and the two databases are synchronised in real time.

I am trying to have sessions stick to the same host, so requests are still load balanced across the 3 workers in each host.

The objective is to avoid two consecutive requests from the same client being sent to different hosts.

My config looks like this:

frontend web_front
  bind *:4100
  default_backend web_back


backend web_back
  cookie SERVERID insert indirect nocache
  balance roundrobin

  server host_1_web_1 129.168.0.1:3000 maxconn 1 check cookie SRV_1
  server host_1_web_2 129.168.0.1:3001 maxconn 1 check cookie SRV_1
  server host_1_web_3 129.168.0.1:3002 maxconn 1 check cookie SRV_1

  server host_2_web_1 129.168.0.2:3000 maxconn 1 check cookie SRV_2
  server host_2_web_2 129.168.0.2:3001 maxconn 1 check cookie SRV_2
  server host_2_web_3 129.168.0.2:3002 maxconn 1 check cookie SRV_2

As you can see, I have set the cookie of each host to the same value, hopping that requests would be still load balanced properly accross workers, but now only the first worker of each host seems to be getting requests.

Is there a way around this? Perhaps using sticky-tables?


Solution

  • If I am correctly understanding you requirements, you want two different levels of load balancing:
    1. Server load balancing using session persistence
    2. Worker load balancing without session persistence.

    One solution would be to have a service in the server side listening for HAProxy connections and doing the load balance across the workers.
    But you still can do this with HAProxy by using a dummy backend:

    frontend web_front
      bind *:4100
      default_backend web_back
    
    backend web_back
      cookie SERVERID insert indirect nocache
      balance roundrobin
      server server1 127.0.0.1:3001 cookie SRV_1
      server server2 127.0.0.1:3002 cookie SRV_2
    
    listen lt_srv1
      bind 127.0.0.1:3001
      server host_1_web_1 129.168.0.1:3000 check
      server host_1_web_2 129.168.0.1:3001 check
      server host_1_web_3 129.168.0.1:3002 check
    
    listen lt_srv2
      bind 127.0.0.1:3002
      server host_2_web_1 129.168.0.2:3000 check
      server host_2_web_2 129.168.0.2:3001 check
      server host_2_web_3 129.168.0.2:3002 check