HAProxy : gérer la persistance des sessions lorsque l’application n’est pas conçue pour
Le problème avec les sessions HTTP c’est qu’elles sont complètement décorrélées des sessions TCP. Sans load balancer, ce n’est pas un problème, par contre dans une architecture multi serveur, un utilisateur peut être redirigé vers un serveur web qui n’est pas au courant de la session HTTP. Ce cas se produit typiquement avec un algorithme de type round robin.
Ainsi, un utilisateur peut lors de la première connexion être authentifié sur un serveur puis lors de l’accès suivant être redirigé vers le second serveur moins chargé.
Habituellement, pour gérer ce type de situation :
- On utilise un système de cache partagé entre les serveurs pour gérer les sessions : base de données, memcache, système de fichier
- L’application gère nativement le mode cluster
- Pour une même IP source, on redirige systématiquement vers le même backend
HAProxy est capable de proposer un autre mode en exploitant la persistance des sessions habituellement utilisée par les applications Web, les cookies HTTP. Pour ce faire, il faut impérativement utiliser le mode http de haproxy et non pas le mode tcp.
Deux façons de faire, ma préférée consiste à réutiliser le cookie d’authentification qui doit être le même pour toutes les applications. Le cookie (PHPSESSID dans cet exemple), est préfixé du backend (s1/s2) entre le navigateur et le load balancer. Cette marque est retirée lors des communications Haproxy vers serveur web :
frontend ft_http bind 10.4.102.10:80 mode http default_backend bk_http backend bk_http mode http balance source hash-type consistent cookie PHPSESSID prefix nocache server s1 10.4.102.5:80 check cookie s1 server s2 10.4.102.6:80 check cookie s2
Dans le second mode, HAProxy va insérer un cookie (BACKENDID) qui sera utilisé lors des communications ultérieures entres le navigateur et le load balancer pour aiguiller les communications proprement.
frontend ft_http bind 0.0.0.0:80 mode http default_backend bk_http backend bk_http mode http balance source hash-type consistent cookie BACKENDID insert indirect nocache server s1 10.0.0.10:80 check cookie s1 server s2 10.0.0.20:80 check cookie s2