我在 haproxy 日志中看到类似以下的错误:
Jul 18 17:05:30 localhost haproxy[8247]: 188.223.50.7:51940 [18/Jul/2011:17:05:24.339] http_proxy_ads http_proxy_ads/<NOSRV> -1/-1/-1/-1/6001 408 212 - - cR-- 100/89/0/0/0 0/0 "<BADREQ>"
Jul 18 17:05:30 localhost haproxy[8247]: 188.223.50.7:51943 [18/Jul/2011:17:05:24.341] http_proxy_ads http_proxy_ads/<NOSRV> -1/-1/-1/-1/6000 408 212 - - cR-- 99/88/0/0/0 0/0 "<BADREQ>"
ETC...
到目前为止,我已尝试增加客户端超时(从 3 秒增加到 6 秒),并将 http 请求缓冲区从 16k 增加到 32k。错误仍然出现。
有人可以指导我在这里寻找什么吗?
答案1
如果浏览器没有使用所有连接,浏览器的预连接也可能导致BADREQ
这种情况。例如,当用户在每个浏览器中只下载一个文件时。
这意味着有两个可能的原因(BADREQ
已使用 HAProxy v1.5-dev24 验证):cR--
CR--
- 未使用的连接:这意味着对于 HTTP(S),客户端通过 TCP 连接,但直到
timeout http-request
(CR--
) 或客户端再次关闭连接 (cR--
) 才发送 HTTP 请求标头。原因:来自普通客户端或负载均衡器的预连接或来自扫描的未使用连接。 - 错误请求。客户端发送了错误请求。这些错误应该在每个统计套接字中可见(请参阅 womble 之前的回答)。
大多数现代浏览器(例如 Firefox 或 Chrome)都在预连接我发现 Firefox 或 Chrome 总是打开至少 2 个连接,即使浏览器只执行一个请求,例如下载文件(例如仅下载http://cdn.sstatic.net/serverfault/img/favicon.ico
)
增加 HAProxy 配置中的值timeout http-request
有助于减少此类未使用连接的日志条目,因为值越高意味着客户端使用该连接的可能性越大,但您也面临服务器无法再处理所有打开(空闲)连接的风险。如果您在 HAProxy 前面使用其他负载均衡器(如 Amazon ELB),请检查 HAProxy 中的超时是否与负载均衡器匹配,因为它们也可能使用预连接。
对于未使用的连接,您可以option dontlognull
在 HAProxy 中禁用此日志条目。引用自HAProxy 文档对于此选项:
通常建议不要在不受控制的环境(例如:互联网)中使用此选项,否则不会记录扫描和其他恶意活动。
答案2
=> The client never completed its request, which was aborted by the
time-out ("c---") after 5s, while the proxy was waiting for the request
headers ("-R--"). Nothing was sent to any server, but the proxy could
send a 408 return code to the client.
解决方案:将“超时 http 请求”更改为 20 秒或更长,而不是 5 秒。
答案3
在这个问题上浪费了一天时间。我们发现一些请求标头太大。HAProxy 的默认最大大小为 8k(所有标头合计),而我们公司喜欢使用 Cookie。在我们的案例中,大约 8% 的请求标头太大,因此截断第 8092 个字节之后。
来自文档:
如果 HTTP 请求大于 (tune.bufsize - tune.maxrewrite),haproxy 将返回 HTTP 400 (Bad Request) 错误。同样,如果 HTTP 响应大于此大小,haproxy 将返回 HTTP 502 (Bad Gateway)。
我们haproxy.cfg
使用以下值更新了文件:
global
# request limit is (bufsize - maxrewrite), our desired limit is 16k (8k is default)
tune.maxrewrite 16384
tune.bufsize 32768
希望能帮助到你!
答案4
BADREQ 只是表示客户端发送了一个错误请求;在 HTTP 模式下,这可能意味着客户端出错了,你对此无能为力。要查看确切的错误是什么,请连接到统计套接字(使用 socat)并运行show errors
。很有可能有人试图在其他 Web 服务器上运行漏洞,因此你可以忽略它。