haproxy: Einrichten eines TCP-Verbindungscaches für einen HTTP-Server

1976
mathieu

Ich versuche, einen lokalen TCP-Verbindungscache einzurichten, um Zugriff auf einen Remote-HTTP-Server für mehrere lokale Anwendungen zu ermöglichen.

Ich habe mit der Konfiguration von haproxy begonnen:

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 

Dies sollte mir erlauben, den lokalen Proxy ( http: // localhost: 4443 ) zu verwenden, um mit https://graph.facebook.com zu sprechen

Und ja, es funktioniert irgendwie:

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

Wenn ich jedoch mein lokales Interface tcpdump, um zu sehen, was graph.facebook.com läuft, sehe ich, dass jedes Mal, wenn ich das obige ausführt, eine neue TCP-Verbindung erstellt wird:

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

Daher meine Frage: Was habe ich hier falsch gemacht? Ich möchte, dass mein lokaler Haproxy-Server die TCP-Verbindungen zu graph.facebook.com so lange wie möglich offen hält, um sie für mehrere Clients und Anforderungen wiederverwenden zu können. Es sieht jedoch so aus, als ob Haproxy die TCP-Verbindungen trotz Bedarf erstellt und abbricht Option http-keep-alive.

Irgendwelche Ideen ?

2

1 Antwort auf die Frage

1
nKn

In der HAproxy-Dokumentation heißt es konkret in diesem 1.1. The HTTP transaction modelAbschnitt:

Standardmäßig arbeitet HAProxy in Bezug auf persistente Verbindungen in einem tunnelartigen Modus: Für jede Verbindung verarbeitet es die erste Anforderung und leitet alles andere (einschließlich zusätzlicher Anforderungen) an den ausgewählten Server weiter. Sobald die Verbindung hergestellt ist, bleibt sie sowohl auf der Client- als auch auf der Serverseite bestehen. Verwenden Sie die Option "http-server-close", um die persistenten Clientverbindungen beizubehalten, während Sie jede eingehende Anforderung einzeln bearbeiten und nacheinander an Server im HTTP-Schließen-Modus weiterleiten. Verwenden Sie die Option "httpclose", um beide Seiten in den HTTP-Modus "Schließen" zu schalten. "Option forceclose" und "Option http-pretend-keepalive" helfen dabei, Server zu umgehen, die sich im HTTP-Schließen-Modus fehlerhaft verhalten.

Sie haben die http-keep-aliveDirektive definiert und keinen der oben beschriebenen Parameter verwendet. Daher müssen Sie im Tunnelmodus arbeiten (außerdem habe ich mehrere HAproxy-Konfigurationen, die Ihren sehr ähnlich sind, und ich kann Ihnen versichern, dass sie wie in der Dokumentation beschrieben funktioniert).

Ich denke, der Täter ist die Art und Weise, wie Sie curlIhre Konfiguration testen. Sie übergeben das -xFlag, was bedeutet, dass Sie den nächsten Parameter als Proxy verwenden möchten. HAproxy verhält sich jedoch bereits so. Die Anfrage sollte also so aussehen:

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

Auf diese Weise senden Sie die Anfrage direkt an HAproxy und verwenden HAproxy nicht als Proxy (da sich dies auf diese Weise verhält).

Ich habe es gemäß dem Vorschlag versucht, aber ich erhalte Folgendes: <HTTP / 1.1 301 dauerhaft verschoben <Ort: http://www.facebook.com/ <X-Content-Type-Optionen: nosniff <Content-Type: text / html < X-FB-Debuggen: cPfFb58L4BkZsGHfyVA5TFuZ7b8cgcrY1jWYulBRk + YB22vv8Q9swKTA9jGUnxs58ZEoK1sxY7DqaOfmwyqQxQ == <Date: Tue, 22 Sep 07/27 mathieu vor 8 Jahren 0
Vermutlich eine fehlende Option zum "curl". Der beste Weg, dies zu testen zugreift direkt über einen Webbrowser und Öffnung `http: // your_haproxy_ip: 4443 / v2.4 / me Felder = id% 2Cname & access_token = CAACEdEose0cBAPvPqQ IAjacV1whsrRfcchVVOXZAgi9ZC56HBVOh5PfI9IZBA12nAmsu9Q9Pznv1e6iZBsnbr4u2nCASnvZBGim BjdWErUXTRQetn0fdV0HLZB68tS0idelR35ybiWnehK5oec9dM9LxjRvFwTpuHSUkeA9nBAyFZBrGf4Fc ZAXuhT2uj5vjbvYkzupyi4mBFlBGfBEIjpeb` nKn vor 8 Jahren 0
Ich schrieb das folgende Test-Python-Skript: http://paste.ubuntu.com/12519941/ So bekomme ich die richtige Antwort von der GET-Anforderung, aber tcpdump zeigt immer noch SYN + RST auf facebook.com für jede Anforderung an. Http: // paste.ubuntu.com/12519949/ mathieu vor 8 Jahren 0
Um den obigen Kommentar zu verdeutlichen, AFAICT, sehe ich, dass Haproxy die serverseitige Verbindung aufrechterhält, jedoch nur innerhalb der Dauer der clientseitigen TCP-Verbindung. Es scheint also nicht möglich zu sein, die serverseitige Verbindung über mehrere HTTP-Anforderungen in mehreren TCP-Verbindungen offen zu halten. mathieu vor 8 Jahren 0
Das ist seltsam. Wenn die Anforderungen mit einer Intervalldifferenz von weniger als 50 Sekunden gemacht werden, sollten sie nicht über verschiedene TCP-Verbindungen erfolgen. Sie sollten dieselbe verwenden. Ich habe nur noch den Verdacht, dass sich die Timeout-Intervalle zwischen Client und Server gegenseitig beeinträchtigen. Ein weiterer interessanter Test wäre der Versuch, eine andere Website als Facebook zu verwenden, um zu sehen, ob es sich genauso verhält. nKn vor 8 Jahren 0
Gleicher Test mit einem einfachen HTTP-Server, gleiches Ergebnis. Konfiguration: http://paste.ubuntu.com/12521224/ Testskript: http://paste.ubuntu.com/12521231/ tcpdump für zwei sequenzielle Anforderungen auf zwei separaten TCP-Verbindungen. Clientseitig werden zwei separate TCP-Verbindungen zum Server von ausgelöst haproxy: http://paste.ubuntu.com/12521242/ mathieu vor 8 Jahren 0
Interessant. Welche Version verwendest du? Ich habe Ihr Beispiel mit minimalen Modifikationen ausprobiert und der Tunnel bleibt für weitere Anfragen offen. nKn vor 8 Jahren 0
verison: 1.5.14, FC22 mathieu vor 8 Jahren 0
Ich verwende 1.4.24 auf Ubuntu 14.04. Ich frage mich, ob das wichtig ist, aber wie ich in meinem Fall sagte, funktioniert es wie erwartet. nKn vor 8 Jahren 0
ok, gut, ich habe immer noch keine Lösung für mein Problem gefunden, aber ich denke, es ist fair, Ihnen die Prämie zu gewähren, die Sie mit Ihrer umfangreichen Hilfe bei der Fehlersuche erhalten haben. mathieu vor 8 Jahren 0
Vielen Dank! Lassen Sie mich wissen, ob ich Ihnen mit zusätzlichen Tests helfen kann nKn vor 8 Jahren 0