HAProxy 似乎无缘无故地返回错误请求(无效主机)

Dav*_*vid 4 haproxy 400 bad-request

我一直在尝试测试如下所示的设置:

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

我将 Nginx 和 HAProxy 放在同一台 Debian 机器上。但是,HAProxy 不断返回“Bad Request (Invalid Host)”。我已经确定 HAProxy 有问题,首先将请求直接从网站发送到 .Net 应用程序,该应用程序有效。将 Nginx 链接到 .Net 应用程序也有效。但是,当我尝试使用 HAProxy 进行测试时,我开始收到错误消息。.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"
Run Code Online (Sandbox Code Playgroud)

我的配置文件如下所示:

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
Run Code Online (Sandbox Code Playgroud)

我之前没有使用 HAProxy 的经验,我正在使用它,因为它是推荐给我的。因此,我不知道我可以采取哪些其他步骤来解决这个问题。配置手册提到了您可以设置的各种选项,例如 tune.bufsize 和选项 accept-invalid-http-request 但这些都没有效果。

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

小智 8

我遇到了同样的问题,我花了一段时间才弄清楚为什么会这样。

我的环境由 1 个 HAproxy 和 2 个 nginx 组成,作为后端,nodejs 作为 CGI 之类的。

根本原因是基于 HAproxy 如何构建 HTTP 请求。默认情况下 HAproxy 不会在请求中包含主机头,因此您需要手动添加,否则 nginx 将默认返回 400 并且 HAproxy 会将其标记为不健康。

示例如下:

  • HAproxy 健康检查配置:

    option httpchk HEAD / HTTP/1.1
    
    Run Code Online (Sandbox Code Playgroud)
  • 等效的 HTTP 请求:

    tony@calderona:~ $ telnet A.B.C.D 80
    Trying A.B.C.D...
    Connected to A.B.C.D.
    Escape character is '^]'.
    HEAD / HTTP/1.1
    
    HTTP/1.1 400 Bad Request
    Server: nginx/1.10.3
    Date: Sun, 10 Dec 2017 09:52:12 GMT
    Content-Type: text/html
    Content-Length: 173
    Connection: close 
    
    Run Code Online (Sandbox Code Playgroud)
  • HAproxy 健康检查配置:

    option httpchk HEAD / HTTP/1.1\r\nHost:\ www.temporaryworkaround.org
    
    Run Code Online (Sandbox Code Playgroud)
  • 等效的 HTTP 请求:

    tony@calderona:~ $ telnet A.B.C.D 80
    Trying A.B.C.D...
    Connected to A.B.C.D.
    Escape character is '^]'.
    HEAD / HTTP/1.1
    host: www.temporaryworkaround.org
    
    HTTP/1.1 200 OK
    Server: nginx/1.10.3
    Date: Sun, 10 Dec 2017 09:52:24 GMT
    Content-Type: text/html; charset=utf-8
    Content-Length: 10282
    Connection: keep-alive
    
    Run Code Online (Sandbox Code Playgroud)

干杯


daf*_*aff 2

如果您想查看 HAproxy 遇到的确切错误,您可以使用socat连接到管理套接字来执行此操作。socat通过安装apt-get install socat,然后运行以下命令:

echo "show errors" | socat unix-connect:/run/haproxy/admin.sock stdio
Run Code Online (Sandbox Code Playgroud)

如果您在收到“错误请求”错误后立即运行此命令,它应该准确地显示 HAproxy 不喜欢客户端发出的 HTTP 请求的哪些内容。

注意:以上仅当您启用Unix Socket commandsHAProxy. 您必须在global部分下添加一行配置才能启用此功能。

global
     stats socket /var/run/haproxy.sock mode 600 level admin
Run Code Online (Sandbox Code Playgroud)

官方文档