HAProxy 2.0 - Wiederholung einiger Anfragen basierend auf der URL

HAProxy 2.0 - Wiederholung einiger Anfragen basierend auf der URL

Ich habe HAProxy Version 2.0.14 installiert und suche nach einem besonderen Anwendungsfall, den ich noch nicht richtig konfigurieren konnte.

Im Grunde habe ich ein Frontend, das auf einem Port lauscht, und zwei Backend-Server. Sobald eine Sitzung gestartet wird, werden Cookies verwendet, sodass eine Sitzung an einen bestimmten Backend-Server gebunden ist und nicht mit einem anderen Server geteilt werden kann. Um dies zu erreichen, verwende ich Schlüsselwörter stick-tableund stick onein LUA-Skript, um den erforderlichen Wert aus den Anfragen zu erhalten.

Wenn jedoch beim Eintreffen der ersten Anfrage der ausgewählte Backend-Server nicht rechtzeitig antwortet, sollten wir ein Failover auf den anderen Server durchführen, da zu diesem Zeitpunkt das Cookie noch nicht gesetzt ist.

Bisher habe ich folgende Konfiguration:

global
   log 127.0.0.1 len 10000 local2 debug
   chroot /var/lib/haproxy
   user haproxy
   group haproxy
   daemon
   lua-load /opt/LUA/myparser.lua

   stats socket /etc/haproxy/haproxysock level admin

defaults
   log global
   option httplog
   option dontlognull
   mode http
   timeout connect 5000
   timeout client 50000
   timeout server 50000
   log-format "Client IP:port = [%ci:%cp], Start Time = [%tr], Frontend Name = [%ft], Backend Name = [%b], Backend Server = [%s], Time to receive full request = [%TR ms], Response time = [%Tr ms], Status Code = [%ST], Bytes Read = [%B]"

frontend chatgw_front
   bind *:8776

   option http-buffer-request
   declare capture request len 40000
   http-request capture req.body id 0
   http-request capture req.hdrs len 2048

   http-request track-sc0 src table my_back
   use_backend my_back

backend my_back
   balance roundrobin

   stick-table type string len 32 size 30k expire 30m
   stick on "lua.parseId" table my_back

   server server1 x.x.x.1:8080 check
   server server2 x.x.x.2.8080 check

Wenn der ausgewählte Backend-Server nicht innerhalb von 50 Sekunden antwortet, wird ein HTTP 504 Gateway Timeout an den Client gesendet. Stattdessen bräuchte ich, wenn dies die erste Anfrage in einer Sitzung ist, dann (und nur dann) ein Failover auf einen anderen Backend-Server. Anhand der URL können wir erkennen, dass dies die erste Anfrage ist.

Ich habe versucht, das Backend wie folgt zu ändern:

backend my_back
   balance roundrobin

   stick-table type string len 32 size 30k expire 30m
   stick on "lua.parseId" table my_back

# Check if this is "init" request: in this case URL contains "/init"
   acl is_init path_sub /init

# In case of "init" request, enable redispatch to other backend server in case failure
   option redispatch if is_init

# In case of other requests (not "init"), we are already tied to a selected backend server due to session cookie, so disable redispatch
   no option redispatch if !is_init

   server server1 x.x.x.1:8080 check
   server server2 x.x.x.2.8080 check

Ich habe jedoch genau das gleiche Verhalten erhalten. Also habe ich versucht, „retry-on“ hinzuzufügen:

backend my_back
   balance roundrobin

   stick-table type string len 32 size 30k expire 30m
   stick on "lua.parseId" table my_back

   acl is_init path_sub /init

   option redispatch if is_init

   no option redispatch if !is_init

   retry-on conn-failure empty-response response-timeout

   server server1 x.x.x.1:8080 check
   server server2 x.x.x.2.8080 check

Jetzt ist es anders: Es hat die erste Anfrage viermal auf demselben Server versucht und dann HTTP 504 zurückgegeben. Dann hat es die nächste Anfrage erhalten (die nicht „init“ ist und daher nicht beim ausgewählten Backend-Server hängen bleiben sollte) und diese wurde stattdessen an den anderen Server gesendet.

Mein Problem besteht im Wesentlichen darin, wie man ein Failover nur bei der ersten Anfrage implementiert. Alle anderen Anfragen müssen immer beim ausgewählten Backend-Server bleiben.

verwandte Informationen