我发现 HAProxy 的行为非常奇怪。我进行了以下设置,旨在允许 example.com/wiki 转到一个服务器,而 example.com/ 转到另一个服务器。问题是 /wiki 似乎只有一半的时间可以工作,/ webserver 也只有一半的时间可以工作。仔细检查后发现,它似乎在两个后端之间切换;可能对它们进行负载平衡,而不是根据 ACL 规则转到特定后端!
另一个奇怪之处是,services-staging.example.com/greenoven 和 staging.example.com 都会转到 kumquat,尽管规则明确规定只有 services-staging 主机应该转到该后端。
我的 HAProxy 配置有问题吗?我是否错误地使用了 acls 或后端?
global
log 127.0.0.1 local1 debug
maxconn 200000
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 200000
contimeout 5000
clitimeout 50000
srvtimeout 50000
stats uri /monitor
stats auth admin:GS01
stats refresh 5s
stats enable
frontend http-in
bind *:80
option forwardfor
#Staging Hosts
acl host_staging hdr(host) -i staging.example.com
acl host_staging_services hdr(host) -i staging-services.example.com
#Production Hosts
acl host_prod hdr(host) -i example.com www.example.com
acl host_prod_services hdr(host) -i services.urbanatla.com
#URL Paths
acl url_wiki url_beg /wiki
acl url_go url_beg /greenoven
acl url_arcgis url_beg /ArcGIS
#Staging Backends
use_backend pluto if host_staging_services url_arcgis
use_backend kumquat if host_staging_services url_go
use_backend kumquat if host_staging url_wiki
use_backend cumberland if host_staging
#Production Backends
use_backend saturn if host_prod_services url_arcgis
use_backend willow if host_prod_services url_go
use_backend willow if host_prod url_wiki
use_backend ganges if host_prod
backend kumquat
server kumquat kumquat.example.com:8080 maxconn 5000
backend cumberland
server cumberland cumberland.example.com:80 maxconn 5000
backend ganges
server ganges ganges.example.com:80 maxconn 5000
backend articdata
server articdata articdata.example.com:80 maxconn 5000
backend saturn
server saturn saturn.example.com:80 maxconn 5000
backend willow
server willow willow.example.com:8080 maxconn 5000
backend pluto
server pluto pluto.example.com:80 maxconn 5000
答案1
看起来它正在重复使用连接,在进行上下文切换时不应该这样做。我添加了以下内容:
option httpclose
根据这篇文章:为什么我的 HAProxy 内容切换配置会出现错误?。
所有 URL 和域名现在均可正常工作。
答案2
如果你读过 haproxy文档,你可以找到这一段:
hdr(name) The HTTP header <name> will be looked up in each HTTP request.
Just as with the equivalent ACL 'hdr()' function, the header
name in parenthesis is not case sensitive. If the header is
absent or if it does not contain any value, the roundrobin
algorithm is applied instead.
这可以解释为什么 haproxy 在不遵循 ACL 的服务器之间进行负载平衡。为了确保万无一失,您需要检查是否确实收到了带有host
标头的请求。
我认为您可以使用目标 IP、名称或 URL,而不用检查host
标头。