Unterstützung für HTTP/2-Server-Push ist auch in NGINX Plus R15 enthalten.
Wir freuen uns, Ihnen mitteilen zu können, dass NGINX 1.13.9 , veröffentlicht am 20. Februar 2018 , Unterstützung für HTTP/2-Server-Push bietet. Für NGINX Plus-Benutzer wird HTTP/2-Server-Push-Unterstützung in der kommenden NGINX Plus-Version R15 enthalten sein, die für April 2018 geplant ist.
Server-Push, das in der HTTP/2-Spezifikation definiert ist, ermöglicht es einem Server, Ressourcen präventiv an einen Remote-Client zu pushen, in der Erwartung, dass der Client diese Ressourcen bald anfordern könnte. Auf diese Weise können Sie möglicherweise die Anzahl der RTTs (Round Trip Time – die für eine Anfrage und Antwort benötigte Zeit) bei einem Seitenladevorgang um eine RTT oder mehr reduzieren und so dem Benutzer eine schnellere Antwort bieten.
Mithilfe von Server-Push kann ein Client mit Stylesheets, Bildern und anderen Ressourcen versorgt werden, die er zum Rendern einer Webseite benötigt. Sie sollten darauf achten, nur die Ressourcen zu pushen, die erforderlich sind. Pushen Sie keine Ressourcen, die ein Client wahrscheinlich bereits zwischengespeichert hat.
In diesem Blogbeitrag beschreibe ich:
nghttp
)Link-
HeadersUm beim Laden einer Seite Ressourcen zu pushen, verwenden Sie die Direktive http2_push
wie folgt:
server { # Stellen Sie sicher, dass HTTP/2 für den Server aktiviert ist. Listen 443 ssl http2 ; ssl_certificate ssl/certificate.pem; ssl_certificate_key ssl/key.pem; root /var/www/html; # wenn ein Client demo.html anfordert, pushen Sie auch # /style.css, /image1.jpg und /image2.jpg location = /demo.html { http2_push /style.css; http2_push /image1.jpg; http2_push /image2.jpg; } }
Mit einer der beiden Methoden können Sie ganz einfach überprüfen, ob der Server-Push aktiv ist:
nghttp
So verwenden Sie die Entwicklertools in Ihrem Webbrowser, um am Beispiel von Google Chrome zu überprüfen, ob der Server-Push aktiviert ist. In der Abbildung zeigt die Spalte „Initiator“ auf der Registerkarte „ Netzwerk “ der Entwicklertools von Chrome an, dass im Rahmen einer Anforderung für /demo.html mehrere Ressourcen an den Client gesendet wurden.
nghttp
)Zusätzlich zu den Webbrowser-Tools können Sie den nghttp-
Befehlszeilenclient aus dem nghttp2.org -Projekt verwenden, um zu überprüfen, ob Server-Push aktiv ist. Sie können den nghttp
-Befehlszeilenclient von GitHub herunterladen oder das entsprechende Betriebssystempaket installieren, sofern verfügbar. Verwenden Sie für Ubuntu das Paket nghttp2-client
.
In der Ausgabe markiert das Sternchen (*) Ressourcen, die vom Server gepusht wurden.
$ nghttp -ans https://example.com/demo.html ID AntwortEnde AnfrageStart Prozesscode Größe Anfragepfad 13 +84,25 ms +136us 84,11 ms 200 492 /demo.html 2 +84,33 ms * +84,09 ms 246us 200 266 /style.css 4 +261,94 ms * +84,12 ms 177,83 ms 200 40 K /image2.jpg 6 +685,95 ms * +84,12 ms 601,82 ms 200 173 K /image1.jpg
In vielen Situationen ist es unpraktisch – oder sogar unmöglich –, die Ressourcen, die Sie pushen möchten, in der NGINX-Konfigurationsdatei aufzulisten. Aus diesem Grund unterstützt NGINX auch die Konvention, Link-
Preload-Header abzufangen und dann die in diesen Headern identifizierten Ressourcen zu pushen. Um das Vorladen zu aktivieren, nehmen Sie die Direktive http2_push_preload
in die Konfiguration auf:
server { # Stellen Sie sicher, dass HTTP/2 für den Server aktiviert ist. listen 443 ssl http2 ; ssl_certificate ssl/certificate.pem; ssl_certificate_key ssl/key.pem; root /var/www/html; # Link-Header abfangen und angeforderte Pushes initiieren location = /myapp { proxy_pass http://upstream; http2_push_preload on; } }
Wenn NGINX beispielsweise als Proxy fungiert (für HTTP, FastCGI oder andere Datenverkehrstypen), kann der Upstream-Server seiner Antwort einen Link
-Header wie diesen hinzufügen:
Verknüpfung: </style.css>; als=Stil; rel=preload
NGINX fängt diesen Header ab und leitet einen Server-Push von /style.css ein. Der Pfad im Link
-Header muss absolut sein – relative Pfade wie ./style.css werden nicht unterstützt. Der Pfad kann optional eine Abfragezeichenfolge enthalten.
Um mehrere Objekte zu pushen, können Sie mehrere Link
-Header angeben oder, noch besser, alle Objekte in eine durch Kommas getrennte Liste aufnehmen:
Verknüpfung: </style.css>; als=Stil; rel=preload, </favicon.ico>; als=Bild; rel=preload
Wenn Sie nicht möchten, dass NGINX eine vorinstallierte Ressource pusht, fügen Sie dem Header den Parameter „nopush“
hinzu:
# Ressource wird nicht gepushtLink: </nginx.png>; as=image; rel=preload; nopush
Wenn http2_push_preload
aktiviert ist, können Sie das Preload-Server-Push auch initiieren, indem Sie den Antwortheader in Ihrer NGINX-Konfiguration festlegen:
add_header Link "</style.css>; als=Stil; rel=preload";
Die HTTP/2-Spezifikation befasst sich nicht mit der Herausforderung, zu bestimmen, ob Ressourcen gepusht werden sollen oder nicht. Natürlich empfiehlt es sich, Ressourcen nur dann an Clients weiterzuleiten, wenn Sie wissen, dass diese die Ressource wahrscheinlich benötigen und dass sie diese wahrscheinlich nicht bereits zwischengespeichert haben.
Ein möglicher Ansatz besteht darin, den Clients Ressourcen nur bei ihrem ersten Besuch auf der Site bereitzustellen. Sie können beispielsweise testen, ob ein Sitzungscookie vorhanden ist, und den Link
-Header bedingt festlegen, sodass die Ressourcen nur dann vorab geladen werden, wenn das Sitzungscookie nicht vorhanden ist.
Vorausgesetzt, die Clients verhalten sich gut und schließen das Cookie in nachfolgende Anfragen ein, überträgt NGINX mit der folgenden Konfiguration die Ressourcen nur einmal pro Browsersitzung an die Clients:
Server {
Listen 443 SSL http2 Standardserver;
SSL-Zertifikat ssl/Zertifikat.pem;
SSL-Zertifikatschlüssel ssl/Schlüssel.pem;
Root /var/www/html;
http2_push_preload ein;
Standort = /demo.html {
Add_header Set-Cookie "Sitzung = 1";
Add_header Link $resources;
}
}
Map $http_cookie $resources {
"~*Sitzung = 1" "";
Standard "</style.css>; as=style; rel=preload, </image1.jpg>; as=Bild; rel=preload, </image2.jpg>; as=Bild; rel=preload";
}
Um die Wirkung des Server-Pushs zu messen, haben wir eine einfache Testseite, /demo.html , erstellt, die auf ein separates Stylesheet, /style.css , verweist. Das Stylesheet verweist außerdem auf zwei Bilder. Wir haben die Seitenladezeiten mit drei verschiedenen Konfigurationen getestet:
GET
s (Keine Optimierung) – Der Browser hat Ressourcen geladen, als er erkannte, dass diese benötigt wurdenLink
-Header) wurden in die erste Antwort aufgenommen, um den Browser anzuweisen, die Abhängigkeiten zu ladenWir haben mehrere Testläufe jeder Konfiguration mit HTTP, HTTPS oder HTTP/2 durchgeführt. Die ersten beiden Konfigurationen gelten für alle drei Protokolle und Server-Push nur für HTTP/2.
Das Verhalten wurde mit den Chrome-Entwicklertools gemessen. Das am häufigsten vorkommende Verhalten jeder Konfiguration wurde bewertet und gemittelt, und die Zeiten wurden mit der RTT der Verbindung (gemessen mit Ping
) korreliert, um die mechanische Wirkung jeder Methode zu veranschaulichen.
GET-
Vorgang in etwa 1 RTT abgeschlossen ist.-GET
-Anfrage.keepalive_timeout
und http2_idle_timeout
wurden verwendet, um Keepalive-Verbindungen schnell zu schließen.Dieser Test war bewusst einfach gehalten, um die Funktionsweise der Vorladehinweise und des Server-Pushs hervorzuheben. Server-Push liefert in einfachen Situationen eine 1-RTT-Verbesserung gegenüber Preload-Hinweisen und eine größere Verbesserung im Vergleich zu nicht optimierten, sequenziellen GET-
Anfragen und der Erkennung abhängiger Ressourcen.
In realistischeren Anwendungsfällen gibt es wesentlich mehr Variablen: mehrere abhängige Ressourcen, mehrere Quellen, sogar die Möglichkeit einer Bandbreitenverschwendung durch das Pushen von Ressourcen, die bereits zwischengespeichert sind oder nicht unmittelbar benötigt werden. Auch Browserinkonsistenzen wirken sich auf die Leistung aus. Ihr Kilometerstand wird bei diesem einfachen Test sicherlich abweichen.
Das Chrome-Team hat beispielsweise einige ausführliche Empfehlungen dazu veröffentlicht, wann Server-Push bereitgestellt werden sollte, und hat auf komplexeren Sites Messungen durchgeführt, um die Auswirkungen von fehlender Optimierung, Vorladehinweisen und Server-Push über HTTP/2 zu vergleichen. Ihr Bericht „Faustregeln für HTTP/2-Push“ ist für jeden lesenswert, der den Einsatz von HTTP/2-Server-Push in der Produktion erwägt.
Die pragmatische Schlussfolgerung lautet: Wenn Sie im Voraus ermitteln können, welche Ressourcen erforderlich sind, ist es von echtem Nutzen, wenn Upstream-Server einen Vorladehinweis senden. Der zusätzliche Nutzen durch die Nutzung dieser Ressourcen ist gering, aber messbar, kann aber möglicherweise zu einer Verschwendung von Bandbreite und Verzögerungen bei benötigten Ressourcen führen. Sie sollten alle Server-Push-Konfigurationen sorgfältig testen und überwachen.
Die folgenden Informationen basieren teilweise auf den Untersuchungen in Jake Archibalds sehr detailliertem Blogbeitrag „HTTP/2-Push ist schwieriger als ich dachte“ .
HTTP/2-Server-Push wird normalerweise verwendet, um abhängige Ressourcen präventiv zu senden, wenn der Client eine Ressource anfordert. Wenn ein Client beispielsweise eine Webseite anfordert, kann der Server abhängige Stylesheets, Schriftarten und Bilder an den Client senden.
Wenn ein Client eine HTTP/2-Verbindung herstellt, kann der Server eine oder mehrere Server-Push-Antworten über die Verbindung initiieren. Diese Pushes senden Ressourcen, die der Client nicht explizit angefordert hat.
Der Client kann einen Push entweder ablehnen (durch Senden eines RST_STREAM-
Frames) oder akzeptieren. Der Client speichert den gepushten Inhalt in einem lokalen „Push-Cache“, der mit der HTTP/2-Verbindung verknüpft ist.
Wenn der Client später über eine bestehende HTTP/2-Verbindung eine Anforderung für eine Ressource stellt, prüft er den Push-Cache der Verbindung auf eine abgeschlossene oder in Übertragung befindliche Antwort auf die Anforderung. Dabei wird die zwischengespeicherte Ressource bevorzugt verwendet, anstatt eine neue HTTP/2-Anfrage für die Ressource zu stellen.
Jede gepushte Ressource verbleibt im Push-Cache pro Verbindung, bis (a) sie verwendet wird oder (b) die HTTP/2-Verbindung geschlossen wird:
Dies hat mehrere Auswirkungen:
Eine viel detailliertere Liste der Probleme finden Sie in Jake Archibalds Blogbeitrag „HTTP/2-Push ist schwieriger als ich dachte“ .
HTTP/2-Server-Push ist eine interessante Funktion. Stellen Sie sicher, dass Sie die Push-Konfiguration Ihres HTTP/2-Servers gründlich testen und bereit sind, in Fällen auf Preload-Hinweise zurückzugreifen, in denen dies zu einem vorhersehbareren, Cache-bewussteren Verhalten führt.
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."