Haproxy

Haproxy:同時使用 reqrep 和使用伺服器規則時遇到問題

  • January 14, 2019

我正在嘗試使用use-server規則將幾個後端塊合併為一個。我請求將webadmin.example.org各種 URL 路徑發送到同一個後端,並試圖讓這些請求根據 URL 路徑發送到不同的伺服器。它部分工作,但在某些情況下失敗。Ubuntu 18.04 上的 Haproxy 1.8.8。這是我的配置:

backend webadmin
 # Tried both of these; it balances between servers otherwise.
 #balance source
 balance hdr(host)
 acl path:phpmyadmin path_beg -i /phpmyadmin
 acl path:phppgadmin path_beg -i /phppgadmin
 acl path:rabbitmq path_beg -i /rabbitmq
 acl path:rcmdr path_beg -i /rediscommander
 reqrep ^([^\ ]*\ /)rabbitmq[/]?(.*) \1\2 if path:rabbitmq
 reqrep ^([^\ ]*\ /)rediscommander[/]?(.*) \1\2 if path:rcmdr
 use-server rcmdr:00 if path:rcmdr
 use-server rabbitmq:00 if path:rabbitmq
 use-server nginx:00 if path:phpmyadmin || path:phppgadmin
 # Tried these too.
 #use-server rabbitmq:00 if { path_beg -i /rabbitmq }
 #use-server nginx:00 if { path_beg -i /phpmyadmin } || { path_beg -i /phppgadmin }
 #use-server rcmdr:00 if { path_beg -i /rediscommander }
 server rabbitmq:00 localhost:15672 maxconn 10000 check fall 3 rise 2
 server rcmdr:00 localhost:6670 maxconn 10000 check fall 3 rise 2
 server nginx:00 localhost:6669 maxconn 10000 check fall 3 rise 2

我的經驗是,對 ACL 的請求path:phpmyadminpath:phppgadmin匹配的 ACL 會轉到正確的伺服器(Nginx,其中 URL 路徑被整理到正確的應用程序),但對其他兩個 ACL 的請求似乎忽略了use-server規則,只是轉到任何伺服器在規則列表中首先定義(或者如果使用循環平衡模式,則每個請求都會路由到不同的後端,忽略use-server規則)。

如果我消除reqrep規則,每個請求都會根據use-server規則正確路由。不幸的是,我需要這些規則,以便後端伺服器正確響應請求(即,它們不應該看到子路徑 URL,因為它們對它們一無所知,它們只是用於在 Haproxy 中路由)。

那麼,我可以同時使用reqrep&use-server規則嗎?如果是這樣,怎麼做?

好吧,我使用變數裝配了一些對我有用的東西。正如@Michael - sqlbot 提到的,我假設ACL 類似於按值傳遞的變數,因此即使值的來源發生變化,您也可以將值儲存在其中並使用它們。而且我不知道 Haproxy 有一個set-var功能。我還查看了 Lua 選項,但選擇了這個,因為它可以滿足我的需要。

frontend public
 # ... bind, basic setup, etc.
 # ACLS by request path.
 acl path:rcmdr path_reg ^/rediscommander(/.*)?$
 acl path:rabbitmq path_reg ^/rabbitmq(/.*)?$
 # Set the variables here.
 http-request set-var(txn.rcmdr) bool(true) if path:rcmdr
 http-request set-var(txn.rabbitmq) bool(true) if path:rabbitmq
 acl dom:webadmin hdr_dom(host) -i webadmin.example.org
 use_backend webadmin if dom:webadmin

backend webadmin
 balance hdr(host)
 acl path:phpmyadmin path_beg -i /phpmyadmin
 acl path:phppgadmin path_beg -i /phppgadmin
 # Set the ACL if the variable was set in the frontend.
 acl path:rabbitmq var(txn.rabbitmq),bool
 acl path:rcmdr var(txn.rcmdr),bool
 use-server rcmdr if path:rcmdr
 use-server rabbitmq if path:rabbitmq
 use-server nginx if path:phpmyadmin || path:phppgadmin
 # reqrep doesn't kill our ACLs because they are set based on boolean variables
 # from the frontend, not from mutable request paths tested in the backend.
 reqrep ^([^\ ]*\ /)rabbitmq[/]?(.*) \1\2
 reqrep ^([^\ ]*\ /)rediscommander[/]?(.*) \1\2
 server rabbitmq localhost:15672 maxconn 10000 check fall 3 rise 2
 server rcmdr localhost:6670 maxconn 10000 check fall 3 rise 2
 server nginx localhost:6669 maxconn 10000 check fall 3 rise 2

引用自:https://serverfault.com/questions/948907