haproxy - configurando um cache de conexão TCP para um servidor HTTP

2

Eu estou tentando configurar um cache de conexão TCP local para fornecer acesso a um servidor HTTP remoto para vários aplicativos locais.

Eu comecei a configurar o haproxy para fazer isso:

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

que deve me permitir usar proxy local ( http: // localhost: 4443 ) para falar com https://graph.facebook.com

E sim, isso funciona:

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

No entanto, quando tcpdump minha interface local para ver o que vai graph.facebook.com, vejo que toda vez que eu executar o acima, uma nova conexão TCP é criada:

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
...

Daí a minha pergunta: o que fiz de errado aqui? Eu gostaria que meu servidor haproxy local mantivesse abertas as conexões TCP para graph.facebook.com o maior tempo possível para poder reutilizá-las em vários clientes e solicitações, mas parece que a haproxy está criando e destruindo as conexões TCP conforme necessário, apesar de opção http-keep-alive.

Alguma ideia ?

mathieu
fonte

Respostas:

1

Conforme Documentação do HAproxy , concretamente no 1.1. The HTTP transaction model seção, diz o seguinte:

Por padrão, o HAProxy opera em um modo semelhante a um túnel com relação a   conexões persistentes: para cada conexão, processa o primeiro   solicitar e encaminhar todo o resto (incluindo solicitações adicionais)   para o servidor selecionado. Uma vez estabelecida, a conexão é mantida tanto   nos lados do cliente e do servidor. Use "opção http-server-close" para   preservar as conexões persistentes do cliente ao manipular todas as   solicitar individualmente, despachando-os um após o outro para os servidores,   no modo de fechamento HTTP. Use "opção httpclose" para mudar ambos os lados para   Modo de fechamento de HTTP. "opção forceclose" e "option   http-fingir-keepalive "ajuda a contornar servidores que se comportam mal em   Modo de fechamento de HTTP.

Você definiu o http-keep-alive diretiva e ter usado nenhum dos parâmetros descritos acima, assim, você deve estar operando em modo de túnel (adicionalmente, eu tenho várias configurações HAproxy muito semelhantes ao seu e posso garantir-lhe que está funcionando como a documentação diz).

Eu acho que o culpado é o jeito que você está usando curl para testar sua configuração. Você está passando isso -x flag que significa que você deseja usar o próximo parâmetro como um proxy, no entanto, o HAproxy já age como ele. Então o pedido deve ser algo assim:

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

Dessa forma, você está enviando a solicitação diretamente para o HAproxy e não usando o HAproxy como proxy (porque ele se comportará dessa maneira).

nKn
fonte
Eu tentei de acordo com a sugestão, mas eu entendo isso: & lt; HTTP / 1.1 301 movido permanentemente & lt; Localização: facebook.com & lt; X-Content-Type-Options: nosniff & lt; Tipo de Conteúdo: text / html & lt; X-FB-Depurar: cPfFb58L4BkZsGHfyVA5TFuZ7b8cgcrY1jWYulBRk + YB22vv8Q9swKTA9jGUnxs58ZEoK1sxY7DqaOfmwyqQxQ == & lt; Data: Ter, 22 de setembro de 2015, 07:44:02 GMT & lt; Comprimento do Conteúdo: 0 & lt;
mathieu
Provavelmente, alguma opção ausente para o curl. A melhor maneira de testar isso é acessar diretamente um navegador da web e abrir http://your_haproxy_ip:4443/v2.4/me?fields=id%2Cname&access_token=CAACEdEose0cBAPvPqQ‌​IAjacV1whsrRfcchVVOXZAgi9ZC56HBVOh5PfI9IZBA12nAmsu9Q9Pznv1e6iZBsnbr4u2nCASnvZBGim‌​BjdWErUXTRQetn0fdV0HLZB68tS0idelR35ybiWnehK5oec9dM9LxjRvFwTpuHSUkeA9nBAyFZBrGf4Fc‌​ZAXuhT2uj5vjbvYkzupyi4mBFlBGfBEIjpeb
nKn
Eu escrevi o seguinte script python de teste: paste.ubuntu.com/12519941 Então, eu recebo a resposta certa da solicitação GET, mas o tcpdump ainda mostra SYN + RST para facebook.com para cada solicitação paste.ubuntu.com/12519949
mathieu
Para esclarecer o comentário acima, AFAICT, vejo que haproxy mantém viva a conexão do lado do servidor, mas apenas dentro da duração da conexão TCP do lado do cliente. isto é, parece incapaz de manter a conexão do lado do servidor aberta através de múltiplas solicitações HTTP dentro de múltiplas conexões TCP.
mathieu
Isso é estranho. Se as solicitações forem feitas com menos de 50 segundos de diferença de intervalo, elas não devem ser feitas em conexões TCP diferentes, elas devem usar o mesmo. A única suspeita que tenho é que, de alguma forma, os intervalos de cliente e servidor de timeout estão se frustrando. Outro teste interessante seria tentar um site diferente do que o Facebook para ver se ele funciona da mesma maneira.
nKn