Am HAProxy versiunea 2.0.14 instalată și caut un caz de utilizare deosebit pe care încă nu am reușit să îl configurez corect.
Practic, am un frontend care ascultă pe un port și două servere backend. Odată ce o sesiune este pornită, cookie-urile sunt folosite, astfel încât o sesiune este legată de un anumit server de backend și nu poate fi partajată la un alt server. Pentru a realiza asta folosesc stick-masa
și stai pe
cuvinte cheie și un script LUA pentru a obține valoarea necesară din solicitări.
Cu toate acestea, când sosește prima solicitare, dacă serverul backend selectat nu răspunde la timp, ar trebui să trecem la celălalt, deoarece în acel moment cookie-ul nu este încă setat.
Pana acum am urmatoarea configuratie:
global
log 127.0.0.1 len 10000 local2 depanare
chroot /var/lib/haproxy
utilizator haproxy
haproxy de grup
demonul
lua-load /opt/LUA/myparser.lua
socket statistici /etc/haproxy/haproxysock nivel admin
implicite
jurnal global
opțiunea httplog
opțiunea dontlognull
modul http
timeout connect 5000
timeout client 50000
server timeout 50000
format de jurnal „IP client:port = [%ci:%cp], Ora de pornire = [%tr], Nume front-end = [%ft], Nume backend = [%b], Server back-end = [%s], Ora pentru a primi cererea completă = [%TR ms], Timp de răspuns = [%Tr ms], Cod de stare = [%ST], Bytes Read = [%B]"
frontend chatgw_front
lega*:8776
opțiunea http-buffer-request
declara cererea de capturare 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
echilibru roundrobin
stick-masa tip string len 32 dimensiune 30k expira 30m
rămâneți pe tabelul „lua.parseId” my_back
server server1 x.x.x.1:8080 verifica
server server2 x.x.x.2.8080 verifica
Ceea ce face aceasta este dacă serverul backend selectat nu răspunde în 50 de secunde, acesta trimite clientului un HTTP 504 Gateway Timeout. Ceea ce mi-ar trebui în schimb este, dacă aceasta este prima solicitare dintr-o sesiune, atunci (și numai apoi) trecerea la un alt server backend. Putem spune că aceasta este prima solicitare pe baza adresei URL.
Am încercat să schimb backend-ul astfel:
backend my_back
echilibru roundrobin
stick-masa tip string len 32 dimensiune 30k expira 30m
rămâneți pe tabelul „lua.parseId” my_back
# Verificați dacă aceasta este cererea „init”: în acest caz, adresa URL conține „/init”
acl is_init calea_sub /init
# În cazul solicitării „init”, activați redistribuirea către alt server backend în caz de eșec
opțiunea redispatch if is_init
# În cazul altor solicitări (nu „init”), suntem deja legați de un server backend selectat din cauza cookie-ului de sesiune, așa că dezactivați redistribuirea
nicio opțiune redispatch dacă !is_init
server server1 x.x.x.1:8080 verifica
server server2 x.x.x.2.8080 verifica
Totuși am avut exact același comportament. Așa că am încercat să adaug „retry-on”:
backend my_back
echilibru roundrobin
stick-masa tip string len 32 dimensiune 30k expira 30m
rămâneți pe tabelul „lua.parseId” my_back
acl is_init calea_sub /init
opțiunea redispatch if is_init
nicio opțiune redispatch dacă !is_init
reîncercați conn-failure răspuns gol-timeout
server server1 x.x.x.1:8080 verifica
server server2 x.x.x.2.8080 verifica
Acum, este diferit: a încercat cererea inițială de 4 ori pe același server și apoi a returnat HTTP 504. Apoi a primit următoarea solicitare (care nu este „init”, așa că nu ar trebui să se lipească de serverul backend selectat ), iar acesta a fost trimis pe celălalt server.
Practic, problema mea este: cum să implementez failover-ul numai la prima solicitare? Orice altă solicitare trebuie să se lipească întotdeauna de serverul backend selectat.