【问题标题】:HAproxy domain name to backend mapping for path(url) based routingHAproxy 域名到基于路径(url)的路由的后端映射
【发布时间】:2016-06-21 01:37:08
【问题描述】:

HAProxy 是否支持基于路径的路由的域名到后端映射。

目前它确实支持 vhost 的地图:

frontend xyz
   <other_lines>
   use_backend backend1 if { hdr(Host) -i myapp.domain1.com }
   use_backend backend2 if { hdr(Host) -i myapp.domain2.com }

可以使用地图重写为:

frontend xyz
   <other_lines>
   use_backend %[req.hdr(host),lower,map_dom(/path/to/map,default)]

地图文件内容为:

#domainname  backendname
myapp.domain1.com backend1
myapp.domain2.com backend2

但如果路由是基于如下示例所示的路径:

frontend xyz
   acl host_server_myapp hdr(host) -i myapp.domain.com
   acl path_path1 path_beg /path1
   acl path_path2 path_beg /path2
   use_backend backend1 if host_server_myapp path_path1
   use_backend backend2 if host_server_myapp path_path2

是否可以为这个用例进行映射?使用base 代替 hdr(host) 可能会给出整个路径,但它不会具有域的灵活性,因为base 是字符串比较。有没有其他方法可以将其转换为 haproxy 地图。

【问题讨论】:

  • 文档中有一个map_beg() 转换器。它没有真正解释,但似乎你可以将它与第 7 层 path fetch 一起使用,用于类似于 use_backend %[path,map_beg(... 的内容
  • 但这不会包含域名,path 只会给出请求的路径部分。
  • 啊,我看到您在路径上进行匹配,忽略了您正在测试两个 ACL,一个用于路径,一个用于主机。可能还有一个解决方案,我会更详细地研究它,看看是否可以轻松完成。

标签: haproxy


【解决方案1】:

Layer 7 base fetch 开头--

这将返回第一个 Host 标头和路径部分的连接 请求,从第一个斜杠开始,在问题之前结束 标记。

...然后使用map_beg() 将字符串的开头与映射匹配。

use_backend %[base,map_beg(/etc/haproxy/testmap.map,default)]

如果映射文件/etc/haproxy/testmap.map 有匹配前缀的行,则使用映射文件中的后端。否则,将使用名为default 的后端(这是map_beg() 的第二个参数——如果映射不匹配则返回的值)。

如果生成的后端实际上不存在,HAProxy 将继续处理请求,就好像根本没有配置此语句一样。

所以你的地图文件看起来像这样:

example.com/foo     this-backend # note, also matches /foo/ba 
example.com/foo/bar that-backend # note, matches /foo/bar
example.org/foo     some-other-backend

要将子域视为与父域等效(例如,将 example.com 和 www.example.com 等效处理,没有映射重复,如 cmets 中所述),regsub() 转换器可用于修改传递给地图的值:

use_backend %[base,regsub(^www\.,,i),map_beg(/etc/haproxy/testmap.map,default)]

【讨论】:

  • 这不是万无一失的,考虑一下后端名为 backend1 和 backend11 的情况,backend1 将前缀匹配这两种情况,这是不正确的。
  • 什么?不,我们不匹配后端前缀。我们正在匹配请求主机名 + 路径前缀。后端名称必须与地图文件第二列中的值完全相同。
  • 抱歉忽略了这一点,所以如果它是一个基本匹配,它不关心域,它将适用于 example.com/foo 但对于 www.example.com/foo 失败。
  • 是的,但是 www.example.com 和 example.com 是两个不同的主机,就像 example.com 和 example.org 是两个不同的主机一样。您不应该从两个或多个主机名提供相同的内容......您应该将其中一个视为规范,并将另一个重定向到它。否则,复制地图条目或重写主机标头以排除 www. 如果您真的希望站点被视为相同,在进行地图查找之前使用 http-request set-header Host %[hdr(host),regsub(^www\.,,i)] if { hdr_beg(host) -i www. } 之类的东西。
  • 或者甚至在查找use_backend %[base,regsub(^www\.,,i),map_beg(/etc/haproxy/testmap.map,default)]的途中修改中间值,它将使用修改后的主机名进行地图查找,而不更改base。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 2014-09-07
  • 2018-01-28
  • 2019-06-24
  • 1970-01-01
  • 2014-01-03
  • 2020-11-20
相关资源
最近更新 更多