HAProxy 2.0 - tentando novamente algumas das solicitações com base no URL

HAProxy 2.0 - tentando novamente algumas das solicitações com base no URL

Tenho o HAProxy versão 2.0.14 instalado e estou procurando um caso de uso peculiar que ainda não consegui configurar corretamente.

Basicamente eu tenho um frontend que escuta em uma porta e dois servidores backend. Depois que uma sessão é iniciada, os cookies são usados, portanto, uma sessão fica vinculada a um servidor back-end específico e não pode ser compartilhada com outro servidor. Para conseguir isso, estou usando stick-tablepalavras stick on-chave e um script LUA para obter o valor necessário das solicitações.

Porém, quando a primeira solicitação chegar, se o servidor backend selecionado não responder a tempo, devemos fazer o failover para o outro, pois nesse ponto o cookie ainda não está definido.

Até agora tenho a seguinte configuração:

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

O que isso faz é que, se o servidor back-end selecionado não responder em 50 segundos, ele lançará um HTTP 504 Gateway Timeout para o cliente. Em vez disso, o que eu precisaria é que, se esta for a primeira solicitação em uma sessão, então (e somente então) faça failover para outro servidor back-end. Podemos dizer que esta é a primeira solicitação baseada na URL.

Tentei mudar o backend assim:

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

No entanto, obtive exatamente o mesmo comportamento. Então tentei adicionar "retry-on":

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

Agora é diferente: ele tentou a requisição inicial 4 vezes no mesmo servidor, e depois retornou o HTTP 504. Aí ele recebeu a requisição seguinte (que não é "init", então não deve ficar grudando no servidor backend selecionado ), e isso foi enviado para o outro servidor.

Basicamente, meu problema é: como implementar o failover apenas na primeira solicitação? Qualquer outra solicitação deve sempre seguir o servidor backend selecionado.

informação relacionada