Назад | Перейти на главную страницу

Haproxy: проблемы с использованием правил reqrep и use-server вместе

Я пытаюсь объединить несколько бэкэнд-блоков в один, используя 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