关于 HAProxy reqrep 的快速问题。我正在尝试重写/替换发送到后端的请求。
我有以下示例域和 URI,它们共享相同的域名,但后端 Web 服务器池不同。
http://domain/web1
http://domain/web2
我希望 web1 转到后端 webfarm1,web2 转到 webfarm2。目前确实如此。但是,当请求发送到后端时,我想删除 web1 或 web2 URI。
这是我的 haproxy.cfg
frontend webVIP_80
mode http
bind :80
#acl routing to backend
acl web1_path path_beg /web1
acl web2_path path_beg /web2
#which backend
use_backend webfarm1 if web1_path
use_backend webfarm2 if web2_path
default_backend webfarm1
backend webfarm1
mode http
reqrep ^([^\ ]*)\ /web1/(.*) \1\ /\2
balance roundrobin
option httpchk HEAD /index HTTP/1.1\r\nHost:\ example.com
server webtest1 10.0.0.10:80 weight 5 check slowstart 5000ms
server webtest2 10.0.0.20:80 weight 5 check slowstart 5000ms
backend webfarm2
mode http
reqrep ^([^\ ]*)\ /web2/(.*) \1\ /\2
balance roundrobin
option httpchk HEAD /index HTTP/1.1\r\nHost:\ example.com
server webtest1-farm2 10.0.0.110:80 weight 5 check slowstart 5000ms
server webtest2-farm2 10.0.0.120:80 weight 5 check slowstart 5000ms
如果我转到http://domain/web1
或http://domain/web2
在错误日志中看到每个后端服务器上的请求分别是针对资源 /web1 或 /web2 的。因此,我相信我的正则表达式有问题,即使我从文档中复制并粘贴了它。http://code.google.com/p/haproxy-docs/wiki/reqrep
摘要:我正在尝试根据 URI 路由流量,但是我希望 HAProxy 在将请求发送到后端池时删除 URI。
谢谢你!
-吉姆
答案1
你有这个:
reqrep ^([^\ ]*)\ /web1/(.*) \1\ /\2
我想你想要这个:
reqrep ^([^\ ]*\ /)web1[/]?(.*) \1\2
区别在于,如果省略 webN 后的 /,第二个方法仍会起作用。
在回答您下面的评论时,详细阐述上述表达式的工作原理比我能给出的要费力得多。不过,也许这会有所帮助。
/web1 之前的所有内容都“捕获”了请求字符串中 web1 之前的所有内容。因此,通常情况下,该字符串为 GET 或 POST。(.*)“捕获”了 web1 之后的所有内容,如果没有任何内容,则不包含任何内容。
下一部分 ( \1\2
) 说明如何处理这些捕获的部分。它表示形成一个由\1
(第一个捕获的部分) 和\2
(后面是第二个捕获的部分) 组成的字符串。由于 web1 从未被捕获,因此它不会被组装到最终输出中。
答案2
从 HAProxy 2.1 版开始,不再有 reqrep 指令。因此,您可以使用以下命令:
http-request replace-path /web1(.*) \1
答案3
将其放在前端
reqirep ^([^\ :]*)\ /(.*) \1\ /web1/\2
很好的一课,学习剥线:https://gist.github.com/PiBa-NL/8ad6c222354cbd7a5af5