haproxy-为 HTTP 服务器设置 TCP 连接缓存

haproxy-为 HTTP 服务器设置 TCP 连接缓存

我正在尝试设置本地 TCP 连接缓存,以便多个本地应用程序可以访问远程 HTTP 服务器。

我已经开始配置 haproxy 来执行以下操作:

global
    log         /dev/log local0
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    log global
    mode http
    option http-keep-alive
    timeout http-keep-alive 60000ms
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend  http-in
    option httplog
    bind  127.0.0.1:4443
    default_backend facebook

backend facebook
    server fb graph.facebook.com:443 maxconn 32 ssl verify none

这应该允许我使用本地代理(http://本地主机:4443) 交谈https://graph.facebook.com

是的,它确实有效:

$ curl -4 -x http://127.0.0.1:4443 -vvv 'http://graph.facebook.com/v2.4/me?fields=id%2Cname&access_token=CAACEdEose0cBAPvPqQIAjacV1whsrRfcchVVOXZAgi9ZC56HBVOh5PfI9IZBA12nAmsu9Q9Pznv1e6iZBsnbr4u2nCASnvZBGimBjdWErUXTRQetn0fdV0HLZB68tS0idelR35ybiWnehK5oec9dM9LxjRvFwTpuHSUkeA9nBAyFZBrGf4FcZAXuhT2uj5vjbvYkzupyi4mBFlBGfBEIjpeb'

然而,当我通过 tcpdump 查看本地接口到 graph.facebook.com 的情况时,我发现每次执行上述操作时,都会创建一个新的 TCP 连接:

19:06:34.409962 IP (tos 0x0, ttl 64, id 51970, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.1.80.42560 > 31.13.64.1.https: Flags [S], cksum 0xc6fe (correct), seq 1868596651, win 29200, options [mss 1460,sackOK,TS val 37375657 ecr 0,nop,wscale 7], length 0
19:06:34.486631 IP (tos 0x0, ttl 86, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    31.13.64.1.https > 192.168.1.80.42560: Flags [S.], cksum 0xc226 (correct), seq 2991458091, ack 1868596652, win 13980, options [mss 1410,sackOK,TS val 3177564556 ecr 37375657,nop,wscale 8], length 0
19:06:34.486705 IP (tos 0x0, ttl 64, id 51971, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.80.42560 > 31.13.64.1.https: Flags [.], cksum 0x262d (correct), seq 1, ack 1, win 229, options [nop,nop,TS val 37375733 ecr 3177564556], length 0
19:06:34.486852 IP (tos 0x0, ttl 64, id 51972, offset 0, flags [DF], proto TCP (6), length 569)
    192.168.1.80.42560 > 31.13.64.1.https: Flags [P.], cksum 0x2730 (correct), seq 1:518, ack 1, win 229, options [nop,nop,TS val 37375733 ecr 3177564556], length 517
19:06:34.578182 IP (tos 0x0, ttl 86, id 52940, offset 0, flags [DF], proto TCP (6), length 52)
    31.13.64.1.https > 192.168.1.80.42560: Flags [.], cksum 0x2474 (correct), seq 1, ack 518, win 59, options [nop,nop,TS val 3177564650 ecr 37375733], length 0
...

因此,我的问题是:我在这里做错了什么?我希望我的本地 haproxy 服务器尽可能长时间保持与 graph.facebook.com 的 TCP 连接打开,以便能够在多个客户端和请求之间重复使用它们,但看起来 haproxy 正在根据需要创建和拆除 TCP 连接,尽管有选项 http-keep-alive。

有任何想法吗 ?

答案1

根据HAproxy 文档具体在1.1. The HTTP transaction model章节中提到:

默认情况下,HAProxy 在持久连接方面以类似隧道的模式运行:对于每个连接,它处理第一个请求,并将所有其他请求(包括其他请求)转发到选定的服务器。一旦建立,连接将在客户端和服务器端都保持。使用“option http-server-close”保留客户端持久连接,同时在 HTTP 关闭模式下单独处理每个传入请求,将它们一个接一个地发送到服务器。使用“option httpclose”将双方都切换到 HTTP 关闭模式。“option forceclose”和“option http-pretend-keepalive”有助于解决 HTTP 关闭模式下服务器行为异常的问题。

您已经定义了http-keep-alive指令,但未使用上述任何参数,因此,您必须在隧道模式下操作(此外,我有几个与您的非常相似的 HAproxy 配置,我可以向您保证它可以按照文档所述工作)。

我认为问题在于您curl测试配置的方式。您向其传递了一个-x标志,这意味着您想使用下一个参数作为代理,但是 HAproxy 已经充当了它。因此请求应该是这样的:

curl 'http://127.0.0.1:4443/v2.4/me?fields=id%2Cname&access_token=CAACEdEose0cBAPvPqQ‌​IAjacV1whsrRfcchVVOXZAgi9ZC56HBVOh5PfI9IZBA12nAmsu9Q9Pznv1e6iZBsnbr4u2nCASnvZBGim‌​BjdWErUXTRQetn0fdV0HLZB68tS0idelR35ybiWnehK5oec9dM9LxjRvFwTpuHSUkeA9nBAyFZBrGf4Fc‌​ZAXuhT2uj5vjbvYkzupyi4mBFlBGfBEIjpeb

这样,您就直接将请求发送给 HAproxy,而不是使用 HAproxy 作为代理(因为它本身会以这种方式运行)。

相关内容