Haproxy路由和基于URI路径的重写

leo*_*vrf 13 regex rewrite load-balancing path haproxy

我正在尝试设置Haproxy来对由uri路径标识的一些后端进行负载均衡请求.例如:

https://www.example.com/v1/catalog/foo/bar

应该导致"catalog-v1"后端.

事情是每个应用程序响应不同的路径,所以我不仅要识别应用程序,还要重写URL路径.例如

我知道我不应该使用Haproxy进行重写,但现在这是不可避免的.

尝试了以下正则表达式,该正则表达式适用于regex101:

([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)
Run Code Online (Sandbox Code Playgroud)

代换:

\1/\3-\2/\4
Run Code Online (Sandbox Code Playgroud)

最后这里是haproxy.config:

global
    daemon
    user root
    group root
    maxconn 256000
    log     127.0.0.1 local0
    log     127.0.0.1 local1 notice
    stats   socket /run/haproxy/stats.sock mode 777 level admin
defaults
    log      global
    option   dontlognull
    maxconn  4000
    retries  3
    timeout  connect 5s
    timeout  client  1m
    timeout  server  1m
    option   redispatch
    balance  roundrobin

listen stats :8088
    mode http
    stats enable
    stats uri /haproxy
    stats refresh 5s

backend catalog-v1
    mode http
    option httpchk GET /catalog-v1/ping
    http-check expect status 200
    reqrep ([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)   \1/\3-\2/\4
    server 127.0.0.1:8280_catalog-v1-node01 127.0.0.1:8280 check inter 2s rise 3 fall 2

backend checkout-v1
    mode http
    option httpchk GET /checkout-v1/ping
    http-check expect status 200
    reqrep ([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)   \1/\3-\2/\4
    server 127.0.0.1:8180_checkout-v1-node01 127.0.0.1:8180 check inter 2s rise 3 fall 2

frontend shared-frontend
    mode http
    bind localhost:80
    acl is-catalog-v1-path path_dir /v1/catalog
    acl is-checkout-v1-path path_dir /v1/checkout
    use_backend catalog-v1 if is-catalog-v1-path
    use_backend checkout-v1 if is-checkout-v1-path
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

我一直在努力解决这个问题很长一段时间没有成功.后端在Haproxy stats页面中显示"UP",但每当我调用"non rewrited url"时,我收到400 Bad Request错误.

在此先感谢您的帮助!

Rhi*_*him 12

如果我理解正确,请替换以下示例:

reqrep ^([^\ ]\*)\ /([-.0-9A-Za-z]\*)/([a-zA-Z]\*)/(.\*)  \1\ /\3-\2/\4
Run Code Online (Sandbox Code Playgroud)

http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#reqrep

reqrep search string [{if | unless} cond]
Run Code Online (Sandbox Code Playgroud)

你没有空格.


Arr*_*n S 6

上面的答案是一个单一的解决方案,不能解释问题的根源。问题在于,当我们实际解析/重写HTTP标头时,许多人都假设我们解析的是完整的URL或仅解析PATH组件。

例如:

curl -iv /sf/ask/1734916221/
*   Trying 151.101.65.69...
> GET /questions/24784517/haproxy-route-and-rewrite-based-on-uri-path HTTP/1.1
> Host: stackoverflow.com
> User-Agent: curl/7.54.0
> Accept: */*
Run Code Online (Sandbox Code Playgroud)

目标是重写GET /some_path HTTP/1.1GET /some_other_path HTTP/1.1

我想说明上述解决方案有效,因为它在match and replace中考虑了HTTP动词。 ^([^\ ]\*)\ (.*)捕获动词并将其用于替换模式。\1 \2