Haproxy:使用 reqrep 和 use-server 规则时遇到问题

Haproxy:使用 reqrep 和 use-server 规则时遇到问题

我正在尝试使用use-server规则将多个后端块合并为一个。我有多个 URL 路径的请求,这些请求webadmin.example.org都指向同一个后端,并且我试图让这些请求根据 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转到正确的服务器(Nginx,其中 URL 路径被排序到正确的应用程序),但对其他两个 ACL 的请求似乎忽略了规则use-server,并且只转到规则列表中首先定义的服务器(或者如果使用循环平衡模式,则每个请求都会路由到不同的后端,而忽略规则use-server)。

如果我删除reqrep规则,每个请求都会根据规则正确路由use-server。不幸的是,我需要这些规则,以便后端服务器正确响应请求(即,它们不应该看到子路径 URL,因为它们对它们一无所知,它们只是用于在 Haproxy 内路由)。

那么,我可以同时使用reqrep&use-server规则吗?如果可以,该如何使用?

答案1

好吧,我使用变量构建了一些对我有用的东西。正如@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

相关内容