Я пытаюсь объединить несколько бэкэнд-блоков в один, используя use-server
правила. У меня есть запросы на webadmin.example.org
с различными путями URL, идущими к одному и тому же бэкэнду, и я пытаюсь заставить эти запросы переходить на разные серверы на основе путей URL. Частично работает, но в некоторых случаях дает сбой. Haproxy 1.8.8 в Ubuntu 18.04. Вот моя конфигурация:
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
Я чувствую, что запросы на path:phpmyadmin
и path:phppgadmin
соответствующие списки ACL отправляются на правильный сервер (Nginx, где URL-пути отсортированы для правильных приложений), но запросы для двух других ACL, похоже, игнорируют use-server
rules, и просто перейдите к любому серверу, который определен первым в списке правил (или, если используется режим балансировки с циклическим перебором, каждый запрос перенаправляется на другой сервер, игнорируя use-server
правила).
Если я устраню reqrep
правила, каждый запрос маршрутизируется должным образом в соответствии с use-server
правила. К сожалению, мне нужны эти правила, чтобы внутренние серверы правильно реагировали на запросы (т.е. они не должны видеть URL-адреса подпути, потому что они ничего о них не знают, они просто используются для маршрутизации в Haproxy).
Итак, могу ли я использовать reqrep
& use-server
правила вместе? Если да, то как?
Что ж, я придумал что-то, что работает для меня, используя переменные. Как упоминал @Michael - sqlbot, я предположил, что списки управления доступом похожи на переменные, передаваемые по значению, поэтому вы можете хранить в них значения и использовать их, даже если источник значения изменится. И я не знал, что у Хапрокси был 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