HAProxy 2.0 - 根据 URL 重试某些请求

HAProxy 2.0 - 根据 URL 重试某些请求

我已经安装了 HAProxy 版本 2.0.14,并且正在寻找一个我尚未设法正确配置的特殊用例。

基本上,我有一个监听端口的前端和两个后端服务器。一旦启动会话,就会使用 cookie,因此会话会绑定到特定的后端服务器,并且不能共享给其他服务器。为了实现这一点,我使用stick-tablestick on关键字以及 LUA 脚本从请求中获取所需的值。

但是,当第一个请求到达时,如果选定的后端服务器未能及时响应,我们应该故障转移到另一个服务器,因为此时 cookie 尚未设置。

到目前为止我有以下配置:

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

如果所选的后端服务器在 50 秒内没有响应,它会向客户端抛出 HTTP 504 网关超时。我需要的是,如果这是会话中的第一个请求,则(并且只有这样)故障转移到另一个后端服务器。我们可以根据 URL 判断这​​是第一个请求。

我尝试像这样更改后端:

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

但是我得到了完全相同的行为。所以我尝试添加“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

现在,情况不同了:它在同一台服务器上尝试了 4 次初始请求,然后返回了 HTTP 504。然后它收到了下一个请求(不是“init”,因此不应该坚持到选定的后端服务器),并将其发送到另一台服务器。

基本上,我的问题是:如何仅在第一个请求上实现故障转移?任何其他请求都必须始终坚持使用选定的后端服务器。

相关内容