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 Tc
Timerwerten. 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/161
der Tc
Wert also 13 ms. Tc
ist 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