【问题标题】:Haproxy route and rewrite based on URI pathHaproxy 基于 URI 路径的路由和重写
【发布时间】:2014-09-07 04:50:45
【问题描述】:

我正在尝试设置一个 Haproxy 以在 uri 路径标识的几个后端上负载平衡请求。例如:

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

应该导致“catalog-v1”后端。

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

我知道我不应该将 Haproxy 用于重写,但目前这是不可避免的。

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

([a-z.]*)\/([a-z0-9\-\.]*)\/([a-z\-]*)\/(.*)

替换:

\1/\3-\2/\4

最后是 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

我错过了什么吗?

我已经为此苦苦挣扎了很长一段时间,但没有成功。后端在 Haproxy 统计页面中显示“UP”,但每次我调用“非重写 url”时,我都会收到 400 Bad Request 错误。

提前感谢您的帮助!

【问题讨论】:

  • 为什么“不应该使用 Haproxy 进行重写”?

标签: regex path rewrite load-balancing haproxy


【解决方案1】:

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

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

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

reqrep search string [{if | unless} cond]

你没有空格。

【讨论】:

  • 完美运行!我想我确实错过了一些东西。谢谢!
  • 我一直在与类似的问题作斗争。基本上我想重定向 url example.com/test/app/v1/foo/bar -> otherexample.com/v1/app/foo/bar。我尝试将正则表达式 reqrep ^([^\ ]*)\ /([a-zA-Z]\*)/([a-zA-Z]\*)/([0-9A-Za-z]\*)/(.*) \1\ /\4/\3/\5 与服务器配置一起使用为 server name otherexample.com check maxqueue 200 weight 100
【解决方案2】:

上面的答案是一个单一的修复,没有解释问题的根源。问题是,许多人认为我们在解析完整的 URL 或仅解析 PATH 组件,而实际上我们正在解析/重写 HTTP 标头。

例如:

curl -iv https://stackoverflow.com/questions/24784517/haproxy-route-and-rewrite-based-on-uri-path
*   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: */*

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

我想澄清一下,上面的解决方案有效,因为它考虑了匹配和替换中的 HTTP 动词。 ^([^\ ]\*)\ (.*) 捕获动词并在替换模式中使用它。 \1 \2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多