Das HTTP/2-Modul in NGINX

NGINX | 19. Januar 2016

Dieser Blogbeitrag basiert auf einem Vortrag von Valentin V. Bartenev auf der nginx.conf 2015, die im September in San Francisco stattfand.

Inhaltsverzeichnis

Vor ein paar Tagen haben wir das HTTP/2-Modul von NGINX veröffentlicht. In diesem Vortrag gebe ich Ihnen einen kurzen Überblick über das neue Modul.

0:20 Überblick über das Protokoll

HTTP/2 ist weder ein Ersatz für HTTP/1.x noch ein Allheilmittel, sondern eine weitere Transportschicht für HTTP/1 mit Vor- und Nachteilen und im Wesentlichen mit SPDY identisch.

Zunächst möchte ich mit einigen Mythen rund um das neue Protokoll aufräumen.

Viele halten HTTP/2 für einen glänzenden, überlegenen Nachfolger von HTTP/1. Ich teile diese Ansicht nicht, und zwar aus folgendem Grund: HTTP/2 ist eigentlich nur eine weitere Transportschicht für HTTP/1. Das ist keineswegs schlecht, denn dadurch können Sie HTTP/2 nutzen, ohne Ihre Anwendung ändern zu müssen – es funktioniert mit denselben Headern. Sie können HTTP/2 einfach in NGINX aktivieren, und NGINX kümmert sich zuverlässig um alle Protokolldetails.

Aber HTTP/2 ist kein Wundermittel. Es hat sowohl Vor- als auch Nachteile. Es gibt Anwendungsfälle, in denen es gut funktioniert, aber auch Szenarien, in denen es schlecht abschneidet.

1:40 Hauptmerkmale von HTTP/2

Die wichtigsten Merkmale von HTTP/2 sind das Binärformat, Multiplexing, die HPACK-Header-Komprimierung und die komplexe Priorisierung.

HTTP/2 kann als eine neue Version von SPDY betrachtet werden, da es auf SPDY basiert und ein sehr ähnliches Protokoll ist. SPDY ist ein vor einigen Jahren von Google entwickeltes Protokoll, das die Bereitstellung von Webinhalten beschleunigen soll.

NGINX unterstützt SPDY bereits seit zwei Jahren. Daher können Sie die Vorteile von HTTP/2 mithilfe des SPDY-Moduls ausprobieren. Manche würden sagen, HTTP/2 sei lediglich eine ausgereiftere Version von SPDY 3.1.

Falls Sie mit SPDY nicht vertraut sind, werde ich einige wichtige Punkte erläutern. Diese Punkte gelten auch für HTTP/2, da es sich im Grunde um dasselbe Protokoll handelt, das sich lediglich in einigen Details unterscheidet.

Der erste wichtige Punkt ist, dass das Protokoll selbst binär ist. Ich mag binäre Protokolle – sie lassen sich leichter programmieren, und gute binäre Protokolle bieten einige Leistungsvorteile. Allerdings verstehe ich auch die Nachteile dieses Ansatzes.

3:08 HTTP/2 von innen – Binär

Folie, die veranschaulicht, dass die Nutzdaten einer HTTP/2-Anfrage binär vorliegen, während eine HTTP/1.1-Anfrage aus menschenlesbarem Text besteht

Hier sehen Sie eine HTTP/2-Anfrage. Sie sieht ziemlich cool aus und lässt sich, wie Sie sehen, sehr leicht debuggen. Nein, nur ein Scherz. Sie lässt sich nur schwer debuggen. Und das ist einer der Nachteile von Binärprotokollen.

Möglicherweise müssen Sie ein Tool verwenden, um die Anfrage zu dekodieren, oder … nun ja, manchmal müssen Sie die Binärdaten manuell debuggen, weil das Tool fehlerhaft sein kann oder Ihnen möglicherweise nicht alle in den Bits verborgenen Details anzeigt.

Glücklicherweise kann man HTTP/2 meistens einfach in NGINX aktivieren und muss sich nie mit seiner binären Natur auseinandersetzen. Und zum Glück werden die meisten Anfragen von Maschinen verarbeitet. Maschinen können binäre Protokolle wesentlich besser lesen als Menschen.

4:26 HTTP/2 im Inneren – Multiplexing

HTTP/2 multiplext Anfragen und Antworten über eine einzige Verbindung

Der nächste wichtige Aspekt von HTTP/2 ist das Multiplexing. Anstatt Antworten und Anfragen als separate Datenströme über mehrere Verbindungen zu senden und zu empfangen, bündelt HTTP/2 sie in einem einzigen Byte- bzw. Datenstrom. Dabei werden die Daten für verschiedene Anfragen und Antworten in einzelne Abschnitte unterteilt. Jeder Abschnitt verfügt über eine eigene Kennung und ein Größenfeld, sodass der Endpunkt bestimmen kann, welche Daten zu welcher Anfrage gehören.

Der Nachteil besteht darin, dass jeder Datenblock eine eigene Kennung und eigene Felder hat und daher zusätzlich zu den eigentlichen Daten auch Metadaten übertragen werden. Dadurch entsteht ein gewisser Overhead. Wenn Sie also nur einen einzigen Datenstrom haben, etwa beim Ansehen eines Films, ist HTTP/2 kein geeignetes Protokoll, da dadurch lediglich zusätzlicher Overhead entsteht.

Welche Vorteile bietet Multiplexing? Der Hauptvorteil von Multiplexing besteht darin, dass durch die Verwendung nur einer einzigen Verbindung die gesamte Zeit eingespart werden kann, die bei HTTP/1.x für den Handshake beim Erstellen einer neuen Anfrage benötigt würde.

Solche Verzögerungen sind besonders problematisch, wenn TLS ins Spiel kommt. Deshalb unterstützen die meisten Clients HTTP/2 inzwischen nur über TLS. Soweit ich weiß, gibt es keine Pläne, HTTP/2 über unverschlüsseltes TCP zu unterstützen, da dies kaum Vorteile bietet. Der Grund dafür ist, dass TCP-Handshakes nicht so aufwendig sind wie TLS-Handshakes. Daher spart man hier durch das Vermeiden mehrerer Verbindungen nicht viel.

7:09 Hauptmerkmale von HTTP/2 – Header-Komprimierung

HTTP/2 verwendet den speziell entwickelten HPACK-Algorithmus zur Header-Komprimierung

Der nächste wichtige Punkt bei HTTP/2 ist die Header-Komprimierung. Wenn Sie sehr große Cookies haben, können Sie dadurch bei jeder Anfrage oder Antwort Hunderte von Bytes einsparen. Im Allgemeinen bringt die Header-Komprimierung jedoch meist keinen großen Vorteil. Denn selbst wenn Sie einzelne Anfragen betrachten, haben Sie es im Netzwerk letztlich mit einer Paketschicht zu tun. Dabei spielt es kaum eine Rolle, ob Sie hundert oder hundertfünfzig Bytes senden, da daraus letztlich ohnehin ein einziges Paket wird.

Der Nachteil der HTTP/2-Header-Komprimierung besteht darin, dass sie zustandsbehaftet ist [Redaktion – Dies bezieht sich auf die Tabellen, in denen Informationen zur Komprimierung und Dekomprimierung gespeichert werden]. Daher müssen Server und Clients für jede Verbindung Zustandsinformationen vorhalten, was deutlich mehr Arbeitsspeicher beansprucht als bei HTTP/1-Verbindungen. Folglich benötigt jede HTTP/2-Verbindung wesentlich mehr Arbeitsspeicher.

8:40 Hauptmerkmale von HTTP/2 – Priorisierung

Der Priorisierungsmechanismus in HTTP/2 löst das Problem, dass bei nur einem verfügbaren Kanal die wichtigsten Daten zuerst gesendet werden müssen.

Der letzte wichtige Aspekt von HTTP/2 ist der Priorisierungsmechanismus. Dieser löst das durch Multiplexing entstandene Problem. Wenn nur eine Verbindung besteht, steht auch nur ein Übertragungskanal zur Verfügung. Daher muss sorgfältig entschieden werden, welche Antwort als Nächstes über diesen Kanal gesendet wird.

Die Priorisierung ist in HTTP/2 optional, doch ohne sie ergeben sich kaum Leistungsvorteile. Das HTTP/2-Modul in NGINX unterstützt die Priorisierung vollständig – sowohl anhand von Gewichtungen als auch anhand von Abhängigkeiten. Nach allem, was wir bisher gesehen haben, verfügen wir derzeit über die schnellste HTTP/2-Implementierung. Das sind die wichtigsten Punkte zu HTTP/2.

10:06 Geschichte von HTTP/2

Folie zur Entwicklung der Unterstützung von SPDY und HTTP/2 in NGINX-Versionen

Hier ist eine einfache Folie, die die Geschichte von HTTP/2 zusammenfasst. Ziemlich unkompliziert. Sehen wir uns nun an, wie HTTP/2 in der Praxis funktioniert.

10:16 Testseite

Webseite mit einer typischen Mischung verschiedener Ressourcentypen, die zum Testen der Leistung des NGINX-HTTP/2-Moduls verwendet wird

Um zu verstehen, wie HTTP/2 unter verschiedenen Netzwerkbedingungen funktioniert, habe ich einige Benchmark-Tests mit einer typischen Webseite durchgeführt. Dabei handelt es sich einfach um eine HTTP/2-Seite, die ich auf Github gefunden habe. Sie können sehen, wie viele Ressourcen sie enthält und wie groß die einzelnen Ressourcen sind. Ich denke, sie ist ziemlich repräsentativ für eine typische Website.

10:52 Testumgebung

Folie mit einer Beschreibung der Hardware-, Software- und NGINX-Konfiguration, die zum Testen des NGINX-HTTP/2-Moduls verwendet wurde

Hier ist meine Testumgebung, falls Sie den Test reproduzieren möchten.

11:02 DOM-Ladevorgang

Balkendiagramm zum Vergleich der Downloadzeiten von HTTP/1, HTTP/2 und HTTPS in Netzwerken mit unterschiedlichen Latenzzeiten

Und hier ist das Ergebnis, das ich erhalten habe. Sie sehen, dass ich auf der X‑Achse verschiedene Netzwerklatenzen als Paketumlaufzeiten (RTT) in Millisekunden simuliert und anschließend auf der Y‑Achse die Downloadzeit, ebenfalls in Millisekunden, gemessen habe. Bei diesem Test wird die Seitenladezeit bis zu dem Zeitpunkt gemessen, an dem alle Ressourcen der Seite vollständig geladen sind.

Aus dem Diagramm lässt sich ein klarer Trend ablesen: Bei niedrigen Latenzen gibt es keinen nennenswerten Unterschied zwischen HTTP, HTTPS und HTTP/2. Bei höheren Latenzen ist unverschlüsseltes HTTP/1.x die schnellste Option. HTTP/2 liegt an zweiter Stelle, während HTTPS am langsamsten ist.

11:48 Erstes Rendering

Balkendiagramm zum Vergleich der Zeit bis zur Auslieferung des ersten Elements einer Webseite bei HTTP/1, HTTP/2 und HTTPS über Netzwerke mit unterschiedlichen Latenzzeiten

Wie sieht es mit der Zeit bis zum „First Paint“ aus? In vielen Fällen ist dies aus Sicht der Nutzer die wichtigste Kennzahl, denn zu diesem Zeitpunkt sehen sie tatsächlich etwas auf ihrem Bildschirm. Oft ist es weniger entscheidend, wie lange es dauert, bis die Seite vollständig geladen ist. Viel wichtiger ist, wie lange die Nutzer warten müssen, bis sie etwas sehen.

Hier zeigt sich derselbe Trend. Interessant ist bei unserem Test jedoch, dass HTTP/2 bei Latenzen im mittleren Bereich von 30 ms bis 250 ms etwas schneller ist als herkömmliches HTTP, auch wenn der Unterschied sehr gering ist.

12:45 Konfiguration

Folie mit den Voraussetzungen und dem Befehlsargument zum Erstellen einer NGINX-Binärdatei mit dem HTTP/2-Modul sowie der Direktive zum Aktivieren von HTTP/2 in der Konfiguration

Das waren also unsere Benchmarks. Sehen wir uns nun an, wie HTTP/2 und NGINX konfiguriert werden.

Eigentlich ist es ganz einfach. Sie müssen lediglich den Parameter http2 zur Direktive listen hinzufügen. Der wahrscheinlich komplizierteste Schritt besteht darin, die neueste Version von OpenSSL zu installieren, da HTTP/2 die ALPN-Erweiterung [Application-Layer Protocol Negotiation] benötigt und diese erst ab OpenSSL 1.0.2 unterstützt wird.

Wir haben außerdem NPN [Next Protocol Negotiation] für HTTP/2 implementiert, das derzeit mit den meisten Clients funktioniert. Da SPDY jedoch Anfang 2016 eingestellt wird, werden diese die Unterstützung für NPN entfernen. Das bedeutet, dass Sie HTTP/2 derzeit mit der OpenSSL-Version verwenden können, die in vielen Linux-Distributionen enthalten ist. Sie sollten jedoch bedenken, dass dies in naher Zukunft nicht mehr funktionieren wird.

Damit ist alles zur Konfiguration von NGINX für HTTP/2 gesagt, und ich bin am Ende meiner Präsentation angelangt. Vielen Dank.

[Referenzdokumentation für das HTTP/2-Modul]

Fragen und Antworten

F: Werden Sie HTTP/2 auch auf der Upstream-Seite unterstützen oder nur auf der Client-Seite?

A: Derzeit unterstützen wir HTTP/2 nur auf der Clientseite. HTTP/2 kann nicht mit proxy_pass konfiguriert werden. [Redaktion – In der ursprünglichen Version dieses Beitrags wurde dieser Satz fälschlicherweise wie folgt wiedergegeben: „HTTP/2 kann mit proxy_pass konfiguriert werden.“ Wir bitten um Entschuldigung für etwaige dadurch entstandene Unklarheiten.]

Aber welchen Sinn hat HTTP/2 auf der Backend-Seite? Wie Sie den Benchmarks entnehmen können, bietet HTTP/2 in Netzwerken mit geringer Latenz, etwa bei Upstream-Verbindungen, kaum Vorteile.

Außerdem steht Ihnen in NGINX das Keepalive-Modul zur Verfügung, und Sie können einen Keepalive-Cache konfigurieren. Der wichtigste Leistungsvorteil von HTTP/2 besteht darin, zusätzliche Handshakes zu vermeiden. Wenn Sie dies jedoch bereits mit einem Keepalive-Cache erreichen, benötigen Sie auf der Upstream-Seite kein HTTP/2.

Weitere Ressourcen zu HTTP/2

Möchten Sie HTTP/2 mit NGINX Plus in Ihrer Umgebung ausprobieren? Starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen.


Teilen
Schlagwörter: F5 NGINX, 2016, Tech

Ähnliche Blogbeiträge

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
NGINX | 23.08.2022

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln

Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
NGINX | 08.09.2021

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen

Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
NGINX | 16.08.2021

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet

Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
NGINX | 12.12.2018

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.

Ankündigung von NGINX Plus R16
NGINX | 05.09.2018

Ankündigung von NGINX Plus R16

NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
NGINX | 13.10.2016

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing

Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.