Our application requires cookie based sticky sessions, so we want to use HAproxy to balance incoming traffic towards a farm of IIS servers.
We are using the following config which seems to work on the lab (round-robin working fine and session preserved), but fails when applied in producion with more that 3k concurrent users:
frontend Front_http
bind :80
mode http
default_backend backend_http
stats enable
capture cookie ASP.NET_SessionId len 32
maxconn 10000
frontend Front_https
mode http
default_backend backend_https
bind *:443 ssl crt /etc/haproxy/cert.pem
capture cookie ASP.NET_SessionId len 32
maxconn 10000
backend backend_http
balance roundrobin
option forwardfor
stick-table type ip size 20k expire 5m
appsession ASP.NET_SessionId len 64 timeout 5m request-learn prefix
server Server_1 192.168.10.81:80 cookie Server_1
server Server_2 192.168.10.81:80 cookie Server_2
server Server_3 192.168.10.81:80 cookie Server_3
backend backend_https
balance roundrobin
option forwardfor
stick-table type ip size 20k expire 5m
appsession ASP.NET_SessionId len 64 timeout 5m request-learn prefix
server Server_1 192.168.10.81:80 cookie Server_1 ssl verify none
server Server_2 192.168.10.81:80 cookie Server_2 ssl verify none
server Server_3 192.168.10.81:80 cookie Server_3 ssl verify none
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
From the HAProxy 1.5.8 documentation I understand cookie based stickiness is achieved with command "appsession", but I don't understand the role other commands play, like "capture cookie" or "stick-table", are they necessary at all when using appsession? Can anyone help me understand how they work, and advise if you detect anything wrong with our config.
First of all, could you explain what "does not work" or which problems are you facing with your current configuration?
There are a few issues in your current configuration: - appsession stickness does not resist to a reload. It means stickiness is lost after each reload of HAProxy - you may have a typo in your SSL backend, since you're forwarding SSL traffic to port 80, which is the same port you used for clear HTTP.
HAProxy allows many ways to do cookie based persistence.
cookie insertion: HAProxy set up itself a cookie:
backend mybk
[...]
cookie SERVERID insert indirect nocache
[...]
server s1 10.0.0.1:80 check cookie s1
server s2 10.0.0.2:80 check cookie s2
cookie prefix: HAProxy uses an existing cookie 'usually application one) and prefix its value by the server name:
backend mybk
[...]
cookie ASP.NET_SessionId prefix nocache
[...]
server s1 10.0.0.1:80 check cookie s1
server s2 10.0.0.2:80 check cookie s2
stick table: HAProxy learn and use the application cookie, without modifying it:
backend mybk
[...]
stick-table type string len 64 size 100k expire 15m
stick store-response res.cookie(ASP.NET_SessionId)
stick match req.cookie(ASP.NET_SessionId)
[...]
server s1 10.0.0.1:80 check
server s2 10.0.0.2:80 check
Note: you should use a peers section to keep the data synchronized between 2 HAProxys and when reloading the configuration Note2: the expire parameter should match your application cookie timeout
Last but not least, HAProxy will report you flags about cookie based persistence (understand the one with the cookie keyword) in your log lines. That way, you'll know the status of the request (was there a cookie, was it valid, etc...) and the action taken by HAProxy (insert a new cookie, etc...)
You can have a look at this blog page to get more information about HAProxy: http://blog.haproxy.com/2012/03/29/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/
Baptiste