HAProxy - 需要向 ACL 添加 URL 参数,以区分具有相同 URL 但位于不同端口的服务

HAProxy - 需要向 ACL 添加 URL 参数,以区分具有相同 URL 但位于不同端口的服务

我有多个服务在不同端口上运行,每个服务都使用相同的 URI 路径。例如:

New York Housing Service
127.0.0.1:8080/homes
127.0.0.1:8080/prices

Las Vegas Housing Service
127.0.0.1:8081/homes
127.0.0.1:8081/prices

到目前为止一切都很好,但现在我需要设置 haproxy 来平衡服务负载。因此,我显然需要能够区分它们以进行内容切换。我想我会做的是在 ACL 中的路径中添加一个参数来区分两个后端,在本例中,通过在 ACL 中添加一个 url 参数,后面跟着应用程序的实际路径参数:


frontend http
  maxconn 2000
  bind 0.0.0.0:5000  

  acl new-york path_reg -i /newyork.*
  use_backend nyc-server if new-york

  acl las-vegas path_reg -i /lasvegas.*
  use_backend lv-server if las-vegas

backend nyc-server
  server www.test.com 127.0.0.1:8080 maxconn 100

backend lv-server
  server www.test.com 127.0.0.1:8081 maxconn 100

在此设置中,转到 127.0.0.1:5000/newyork/home 将带我到 127.0.0.1:8080/home,而 127.0.0.1:5000/lasvegas/home 会将我带到 127.0.0.1:8081/home。到目前为止,我的尝试都只是返回了 404 错误。我一直在查看文档,但没有找到与我的用例完全匹配的内容,因此任何帮助都将不胜感激。

编辑:我忘了说我正在使用 haproxy 1.5.18

答案1

后端服务响应 HTTP 404 错误,因为您的 HAPROXY 配置当前正在按原样转发 URL 路径。例如,的 HTTP 请求http://127.0.0.1:5000/newyork/home/wtc.png被转发到nyc-server后端作为http://127.0.0.1:8000/newyork/home/wtc.png

$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 13:00:09--  http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 404 File not found
2020-02-01 13:00:09 ERROR 404: File not found.
$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
127.0.0.1 - - [01/Feb/2020 13:00:09] code 404, message File not found
127.0.0.1 - - [01/Feb/2020 13:00:09] "GET /newyork/homes/wtc.png HTTP/1.1" 404 -

应将 HAproxy 配置为在从后端获取资源时通过剥离第一个路径组件来转换 URL 路径。我建议您reqrep 在前端的定义中添加一个指令,该指令用于操作 HTTP 请求标头的第一行并将类似以下内容转换GET /newyork/homes/wtc.png HTTP/1.1GET /homes/wtc.png HTTP/1.1

frontend http
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2

但是,它不起作用,因为 HAproxy在执行reqrep指令之前会先执行指令use-backend,从而破坏了后端执行:

$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 13:54:55--  http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 503 Service Unavailable
2020-02-01 13:54:55 ERROR 503: Service Unavailable.

第二种可行的方法是在后端定义中重写 URL 路径。但是,根据服务中的后端数量,编写reqrep指令并配置每个后端执行 URL 重写很容易出错。

backend nyc-server
  server www.test.com 127.0.0.1:8080 maxconn 100
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2

backend lv-server
  server www.test.com 127.0.0.1:8081 maxconn 100
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2
$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 14:02:29--  http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 456892 (446K) [image/png]
Saving to: ‘/dev/null’

/dev/null        100%[===============>] 446.18K  --.-KB/s    in 0s      

2020-02-01 14:02:29 (1.83 GB/s) - ‘/dev/null’ saved [456892/456892]

$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
127.0.0.1 - - [01/Feb/2020 14:02:29] "GET /homes/wtc.png HTTP/1.1" 200 -

相关内容