HAProxy返回错误的请求(无效的主机)看似没有理由

我一直在试图testing一个看起来像这样的设置:

网站:Http GET请求 – > Nginx – > HAProxy – > .Net应用程序

我把Nginx和HAProxy放在同一个Debian机器上。 但是,HAProxy经常返回“错误请求(无效主机)”。 我已经确定HAProxy是错误的,首先直接从网站发送请求到.Net应用程序,它的工作。 让Nginx链接到.Net应用程序也可以。 但是,当我尝试使用HAProxy来testing时,我开始出现错误。 .Net应用程序是否实际上在HAProxy后面运行并不重要,我总是得到错误。

我试图发送的消息的一个例子是http://192.168.7.119:81/a:diff1 。 预期的答复是一个JPG图像。 当发送给除HAProxy(Apache,Nginx,应用程序)以外的其他任何东西时,这似乎工作正常,但HAProxy只是说“错误的请求”。 奇怪的是,我没有看到我的日志文件中的任何错误。

以下是日志文件的一个例子:

 Feb 2 15:10:08 companyDebian haproxy[5566]: 192.168.7.114:51105 [02/Feb/2015:15:10:08.415] renderfarm renderfarm/renderA 0/0/0/1/1 400 212 - - ---- 1/1/0/1/0 0/0 "GET /a:diff1 HTTP/1.1" Feb 2 15:10:08 companyDebian haproxy[5566]: 192.168.7.114:51105 [02/Feb/2015:15:10:08.417] renderfarm renderfarm/renderA 73/0/0/4/77 400 212 - - ---- 1/1/0/1/0 0/0 "GET /favicon.ico HTTP/1.1" 

我的configuration文件如下所示:

 global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # Default ciphers to use on SSL-enabled listening sockets. # For more information, see ciphers(1SSL). ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL ssl-default-bind-options no-sslv3 defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http listen renderfarm bind 192.168.7.119:81 mode http balance roundrobin server renderA 192.168.7.114:40000 maxconn 1 

我之前没有使用过HAProxy的经验,因为它被推荐给我。 因此,我不知道我可以采取什么其他措施来解决这个问题。 configuration手册提到了你可以设置的各种选项,比如tune.bufsize和option accept-invalid-http-request,但是这些都没有效果。

注意 :一旦这个设置工作,这个想法是添加更多运行应用程序的服务器。 每台服务器一次只能处理1个请求。

如果你想看到HAproxy运行的确切的错误,你可以使用socat连接到pipe理套接字。 通过apt-get install socat ,然后运行以下命令:

 echo "show errors" | socat unix-connect:/run/haproxy/admin.sock stdio 

如果你在得到一个“错误的请求”错误之后运行它,它应该显示你的客户端发出的HTTP请求到底是什么。

尝试将HAProxyconfiguration更改为TCP而不是HTTP可能是值得的。 你失去了HTTP提供的一些高级的负载平衡选项(为持久性设置cookies等),但是现在看起来你现在看起来不是这样。

下面是一个使用HAProxy进行MySQL负载平衡的示例configuration:

listen mysql-failover bind 10.10.10.210:3306 mode tcp option tcplog option mysql-check user haproxy server db1 10.10.10.13:3306 check fall 2 inter 1000 server backup 10.10.10.11:3306 check

请注意,如果更改为TCP,则将无法访问内置的HTTP统计信息页面,您可以在单独的侦听语句中定义该页面。 例如:

listen stats bind 10.10.10.200:80 mode http stats enable stats hide-version stats uri / option httpclose stats auth username:password

把HAProxy放在Nginx后面看起来很琐碎,因为Nginx或HAProxy都可以单独提供你所需要的function。

考虑使用hostpath_beg将listen部分拆分为frontendbackend部分,并简化configuration,直至获得响应。 另外考虑单独使用forwardfor一个服务器或添加另一个服务器的roundrobin 。 一些例子-

 frontend http-in bind 0.0.0.0:80 acl host_1 hdr(host) -i firstsite.com acl host_nginx hdr(host) -i secondsite.com 

配对前端和后端 –

 use_backend firstsite_redirect if host_1 use_backend nginx if host_nginx 

后端configuration –

 backend firstsite_redirect mode http option forwardfor server firstserver 192.168.0.2:8080 backend nginx mode http balance roundrobin option httpclose option forwardfor cookie SRVNAME insert server nginx01 192.168.0.3:8080 cookie s1 check server nginx02 192.168.0.4:8080 cookie s2 check 

如果您想基于URL进行redirect,请考虑在frontendconfiguration中使用path_beg

 frontend http-in 0.0.0.0:80 acl docs path_beg /docs acl phpmyadmin path_beg /phpmyadmin