HAProxy 2.0 - URLに基​​づいてリクエストの一部を再試行する

HAProxy 2.0 - URLに基​​づいてリクエストの一部を再試行する

HAProxy バージョン 2.0.14 をインストールしていますが、まだ正しく構成できていない特殊なユースケースを探しています。

基本的に、ポートをリッスンするフロントエンドと 2 つのバックエンド サーバーがあります。セッションが開始されると、Cookie が使用されるため、セッションは特定のバックエンド サーバーに結び付けられ、別のサーバーと共有することはできません。これを実現するために、キーワードと LUA スクリプトを使用して、stick-tableリクエストstick onから必要な値を取得します。

ただし、最初のリクエストが到着したときに、選択したバックエンド サーバーが時間内に応答しない場合は、その時点ではまだ 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」ではないため、選択されたバックエンド サーバーに固定されるべきではありません) を受信しましたが、代わりに他のサーバーに送信されました。

基本的に、私の問題は、最初のリクエストのみにフェイルオーバーを実装するにはどうすればよいかということです。他のリクエストは常に、選択されたバックエンド サーバーに固定される必要があります。

関連情報