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

然而我得到了完全相同的行為。所以我嘗試添加“重試”:

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。並且這被發送到其他伺服器。

基本上,我的問題是:如何僅在第一個請求上實現故障轉移?任何其他請求必須始終堅持選定的後端伺服器。

相關內容