HAproxy einfacher Reverse-Proxy, sehr langsam

HAproxy einfacher Reverse-Proxy, sehr langsam

Ich richte gerade eine HAproxy-Maschine ein, die als Reverse-Proxy für einige Websites fungiert. Da die verschiedenen Maschinen nicht physisch verbunden sind, verwende ich OpenVPN, um ein VPN zwischen den Maschinen zu erstellen.

Technisch funktioniert alles. Mein Problem ist jedoch, dass Anfragen, die ich durch den Proxy leite, extrem langsam sind. Ich erhalte zwar irgendwann die vollständige(n) Antwort(en), aber es dauert bis zu 5 Minuten, bis ich so etwas wie ein Jenkins-Dashboard erhalte.

Ich habe es mit einer einfachen statischen HTML-Seite über NGINX und einigen in Go implementierten REST-APIs versucht – das Ergebnis ist immer dasselbe: Ich bekomme die Daten zwar irgendwann, aber es dauert absurd lange.

Hier ist meine HAproxy-Konfiguration:


  global
          log /var/run/log local0 info
          log /var/run/log local0 notice
          daemon
          maxconn 8000
          tune.ssl.default-dh-param 2048
          user nobody
          group nobody

  defaults
          log global
          option httplog
          option dontlognull
          mode http
          timeout connect 5s
          timeout client 1min
          timeout server 1min
          option forwardfor
          option http-server-close
          errorfile 400 /usr/local/etc/haproxy/errorfiles/400.http
          errorfile 403 /usr/local/etc/haproxy/errorfiles/403.http
          errorfile 408 /usr/local/etc/haproxy/errorfiles/408.http
          errorfile 500 /usr/local/etc/haproxy/errorfiles/500.http
          errorfile 502 /usr/local/etc/haproxy/errorfiles/502.http
          errorfile 503 /usr/local/etc/haproxy/errorfiles/503.http
          errorfile 504 /usr/local/etc/haproxy/errorfiles/504.http

  frontend http-in
          bind *:80
          bind *:443 ssl crt /usr/local/etc/haproxy/certs/foo.my.org.pem
          mode http
          use_backend jenkins if { hdr(host) -i foo.my.org }
          use_backend test if { hdr(host) -i bar.my.org }
          default_backend test

  backend jenkins
          server jenkins1 <vpn_ip>:8180
          mode http
          http-request set-header X-Forwarded-Port %[dst_port]
          http-request add-header X-Forwarded-Proto https if { ssl_fc }
          reqrep ^([^\ :]*)\ /(.*)     \1\ /\2
          acl response-is-redirect res.hdr(Location) -m found
          rspirep ^Location:\ (http)://<vpn_ip>:8180/(.*)   Location:\ https://foo.my.org:443/\2  if response-is-redirect

  backend test
          server web01 <vpn_ip>:80

Weitere Informationen:

  • Alle beteiligten Maschinen befinden sich in Rechenzentren und verfügen über eine 1G/1G-Internetverbindung
  • Alle Maschinen laufen unter FreeBSD 11 64-Bit
  • OpenVPN Version 2.4.4 auf allen Maschinen
  • HAproxy Version 1.7.9
  • OpenVPN läuft im TCP-Modus
  • Die HAproxy-Backend-Konfiguration für Jenkins wird übernommen aus demJenkins-Dokumentationaber wie erwähnt besteht das gleiche Problem mit einem Webserver mit bloßem statischem HTML-Inhalt und einem REST-API-Webdienst.

Und hier ist ein Teil des HAproxy-Protokolls beim Zugriff auf die Jenkins-Site:

Feb 27 01:32:24 hostname haproxy[5539]: 213.144.130.227:60243 [27/Feb/2018:01:32:24.093] http-in~ jenkins/jenkins1 0/0/13/134/161 302 153 - - ---- 5/5/0/0/0 0/0 "GET /jenkins HTTP/1.1"
Feb 27 01:32:24 hostname haproxy[5539]: 213.144.130.227:19404 [27/Feb/2018:01:32:24.255] http-in~ jenkins/jenkins1 0/0/25/174/212 200 4492 - - ---- 5/5/0/0/0 0/0 "GET /jenkins/ HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:16321 [27/Feb/2018:01:32:25.330] http-in~ jenkins/jenkins1 0/0/13/30/54 200 8560 - - ---- 6/6/4/4/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/datasource/datasource-min.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:54637 [27/Feb/2018:01:32:25.330] http-in~ jenkins/jenkins1 0/0/27/29/58 200 7585 - - ---- 6/6/3/4/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/autocomplete/autocomplete-min.js HTTP/1.1"Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:59247 [27/Feb/2018:01:32:25.361] http-in~ jenkins/jenkins1 0/0/25/16/51 200 9602 - - ---- 6/6/2/3/0 0/0 "GET /jenkins/static/aeed77bb/jsbundles/page-init.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:40637 [27/Feb/2018:01:32:25.332] http-in~ jenkins/jenkins1 0/0/38/18/81 200 16212 - - ---- 6/6/1/1/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/menu/menu-min.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:10976 [27/Feb/2018:01:32:25.333] http-in~ jenkins/jenkins1 0/0/37/30/95 200 29110 - - ---- 6/6/0/0/0 0/0 "GET /jenkins/static/aeed77bb/scripts/hudson-behavior.js HTTP/1.1"
Sonst sehe ich in den Logfiles nichts. Keine Fehler oder ähnliches.

Kann das am OpenVPN liegen?

Bearbeitung 1:In der Zwischenzeit habe ich dies ohne OpenVPN getestet, indem ich die öffentliche IP-Adresse des Webservers direkt in der HAproxy-Konfiguration verwendet habe. Das Ergebnis ist genau dasselbe.

Antwort1

Ihr Protokoll enthält nicht genügend Informationen, um die 5-minütige Wartezeit zu erklären – sie umfasst weniger als 2 Sekunden –, aber Folgendes fällt auf:

option http-server-close

Dies ist bei einem Back-End auf der anderen Seite einer WAN-Verbindung nicht sinnvoll. Wenn Sie diese Funktion tatsächlich benötigen, muss sie auf einem HAProxy mit extrem geringer Latenz (z. B. lokal) zum Back-End-Server laufen.

Beachten Sie die große Jittermenge in Ihren TcTimerwerten. Dies ist der dritte Wert im Protokollfeld, der wie folgt aussieht:

Tq/Tw/Tc/Tr/Tt

Im ersten Eintrag beträgt 0/0/13/134/161der TcWert also 13 ms. Tcist die Zeit, die zum Herstellen der Verbindung zum Back-End erforderlich ist. Wir sehen hier also, dass Ihr Round-Trip-Jitter ziemlich außer Kontrolle geraten ist und in einem Fall auf fast das Dreifache dieses Wertes ansteigt. Vorausgesetzt, dies wird nicht durch unzureichende Ressourcen auf dem Back-End-Server verursacht, ist dies wahrscheinlich eine Folge der Verwendung von OpenVPN im TCP-Modus – möglicherweise, aber nicht unbedingt, ein Hinweis auf einen Paketverlust.

Sie tunneln TCP (HTTP) innerhalb von TCP (OpenVPN), was normalerweise für nicht interaktive Anwendungen und Anwendungen, bei denen Jitter unwichtig ist, in Ordnung ist, ansonsten jedoch nicht. (Siehe beispielsweiseWarum TCP über TCP eine schlechte Idee istzur Diskussion eines der möglichen Meltdown-Szenarien, allerdings kein ausreichender Grund, diese Konfiguration in einem sauberen Netzwerk vollständig zu vermeiden.) Ich gehe davon aus, dass dies nicht auf OpenVPN zurückzuführen ist, da TCP-Tunnel nicht die gleiche konsistente Latenz wie UDP-Tunnel aufweisen. Wenn Sie durch den Tunnel pingen, sollten Sie sehen, dass sich dieses Jitter auf die Ping-Antwortzeiten auswirkt.

Ändern Sie den Tunnel auf UDP, und das Problem sollte behoben sein. Beachten Sie jedoch, dass die Bedeutung und die Auswirkungen dieses Jitters auf die Leistung – vorausgesetzt, ich liege mit meiner Annahme richtig, dass es sich um eine Nebenwirkung der Verwendung eines TCP-Tunnels handelt – durch die Verwendung von wahrscheinlich übertrieben werden option http-server-close, da bei jeder Anforderung eine neue Verbindung zwischen dem HAProxy und dem Back-End hergestellt werden muss.

Wenn Ihre OpenVPN-Tunnel mit komprimiert sind comp-lzo, sollten Sie dies ebenfalls deaktivieren, da der Mehraufwand die potenziellen Kosteneinsparungen beim Transport aufwiegen könnte.

Antwort2

Es stellte sich heraus, dass dies ein Problem mit der Firewall-/NAT-Konfiguration war.

Wenn jedoch jemand auf dieses Problem stößt, gibt es in der HAproxy-Community weitere Hilfe:https://discourse.haproxy.org/t/reverse-proxy-very-slow-page-load/2172

verwandte Informationen