HTTP/3: Praktische Bereitstellungsoptionen (Teil 3)
Veröffentlicht: 2022-03-10Hallo und willkommen zum letzten Teil dieser dreiteiligen Serie über die neuen HTTP/3- und QUIC-Protokolle! Wenn Sie nach den beiden vorangegangenen Teilen – HTTP/3-Geschichte und -Kernkonzepte und HTTP/3-Leistungsmerkmale – davon überzeugt sind, dass es eine gute Idee ist, mit der Verwendung der neuen Protokolle zu beginnen (und Sie sollten es sein!), dann enthält dieser letzte Teil alles Sie müssen wissen, um loszulegen!
Zuerst besprechen wir, welche Änderungen Sie an Ihren Seiten und Ressourcen vornehmen müssen, um die neuen Protokolle optimal zu nutzen (das ist der einfache Teil). Als Nächstes sehen wir uns an, wie Server und Clients eingerichtet werden (das ist der schwierige Teil, es sei denn, Sie verwenden ein Content Delivery Network (CDN)). Schließlich werden wir sehen, welche Tools Sie verwenden können, um die Auswirkungen der neuen Protokolle auf die Leistung zu bewerten (das ist zumindest vorerst der fast unmögliche Teil).
- Teil 1: Geschichte und Kernkonzepte von HTTP/3
Dieser Artikel richtet sich an Personen, die neu bei HTTP/3 und Protokollen im Allgemeinen sind, und behandelt hauptsächlich die Grundlagen. - Teil 2: HTTP/3-Leistungsmerkmale
Dieser ist mehr in die Tiefe und technisch. Leute, die bereits die Grundlagen kennen, können hier anfangen. - Teil 3: Praktische HTTP/3-Bereitstellungsoptionen
Dieser dritte Artikel der Reihe erläutert die Herausforderungen, die mit der Bereitstellung und dem Testen von HTTP/3 selbst verbunden sind. Es beschreibt auch, wie und ob Sie Ihre Webseiten und Ressourcen ändern sollten.
Änderungen an Seiten und Ressourcen
Beginnen wir mit einer guten Nachricht: Wenn Sie bereits HTTP/2 verwenden, müssen Sie wahrscheinlich nichts an Ihren Seiten oder Ressourcen ändern, wenn Sie zu HTTP/3 wechseln! . Dies liegt daran, dass HTTP/3, wie wir in Teil 1 und Teil 2 erklärt haben, eigentlich eher HTTP/2-über-QUIC ähnelt und die High-Level-Funktionen der beiden Versionen gleich geblieben sind. Daher funktionieren alle für HTTP/2 vorgenommenen Änderungen oder Optimierungen weiterhin für HTTP/3 und umgekehrt.
Wenn Sie jedoch immer noch auf HTTP/1.1 arbeiten oder Ihren Übergang zu HTTP/2 vergessen haben oder die Dinge nie wirklich für HTTP/2 optimiert haben, fragen Sie sich vielleicht, was diese Änderungen waren und warum sie erforderlich waren. Es wäre jedoch auch heute noch schwierig, einen guten Artikel zu finden, der die nuancierten Best Practices beschreibt. Das liegt daran, dass, wie ich in der Einleitung zu Teil 1 gesagt habe, viele der frühen HTTP/2-Inhalte übermäßig optimistisch waren, wie gut es in der Praxis funktionieren würde, und einige davon, ganz offen gesagt, große Fehler und schlechte Ratschläge enthielten. Leider bestehen viele dieser Fehlinformationen bis heute fort. Das ist eine meiner Hauptmotivationen, diese Serie über HTTP/3 zu schreiben, um zu verhindern, dass so etwas noch einmal passiert.
Die beste nuancierte All-in-One-Quelle für HTTP/2, die ich derzeit empfehlen kann, ist das Buch HTTP/2 in Action von Barry Pollard. Da es sich jedoch um eine kostenpflichtige Ressource handelt und ich nicht möchte, dass Sie hier raten müssen, habe ich unten einige der wichtigsten Punkte aufgelistet, zusammen mit ihrer Beziehung zu HTTP/3:
1. Einzelverbindung
Der größte Unterschied zwischen HTTP/1.1 und HTTP/2 war der Wechsel von 6 auf 30 parallele TCP-Verbindungen zu einer einzigen zugrunde liegenden TCP-Verbindung. Wir haben in Teil 2 ein wenig darüber gesprochen, wie eine einzelne Verbindung immer noch so schnell sein kann wie mehrere Verbindungen, da die Überlastungskontrolle bei mehr Verbindungen mehr oder frühere Paketverluste verursachen kann (was die Vorteile ihres aggregierten schnelleren Starts zunichte macht). HTTP/3 setzt diesen Ansatz fort, wechselt aber „nur“ von einer TCP- auf eine QUIC-Verbindung. Dieser Unterschied an sich macht nicht allzu viel (er reduziert hauptsächlich den Overhead auf der Serverseite), aber er führt zu den meisten der folgenden Punkte.
2. Server Sharding und Connection Coalescing
Die Umstellung auf den Einzelverbindungsaufbau war in der Praxis ziemlich schwierig, da viele Seiten über verschiedene Hostnamen und sogar Server (wie img1.example.com
und img2.example.com
) verteilt wurden. Dies lag daran, dass Browser nur bis zu sechs Verbindungen für jeden einzelnen Hostnamen öffneten, sodass mehrere Verbindungen mehr Verbindungen ermöglichten! Ohne Änderungen an diesem HTTP/1.1-Setup würde HTTP/2 immer noch mehrere Verbindungen öffnen, was die tatsächliche Funktionsfähigkeit anderer Funktionen wie Priorisierung (siehe unten) verringern würde.
Daher war die ursprüngliche Empfehlung, das Server-Sharding rückgängig zu machen und die Ressourcen so weit wie möglich auf einem einzigen Server zu konsolidieren. HTTP/2 stellte sogar eine Funktion zur Verfügung, um den Übergang von einer HTTP/1.1-Konfiguration zu erleichtern, genannt Connection Coalescing. Grob gesagt, wenn zwei Hostnamen dieselbe Server-IP (unter Verwendung von DNS) auflösen und ein ähnliches TLS-Zertifikat verwenden, kann der Browser eine einzelne Verbindung auch über die beiden Hostnamen hinweg wiederverwenden .
In der Praxis kann es schwierig sein, das Koaleszieren von Verbindungen richtig hinzubekommen, z. B. aufgrund mehrerer subtiler Sicherheitsprobleme im Zusammenhang mit CORS. Selbst wenn Sie es richtig einrichten, könnten Sie immer noch leicht zwei separate Verbindungen haben. Die Sache ist, das ist nicht immer schlecht . Erstens könnte die einzelne Verbindung aufgrund schlecht implementierter Priorisierung und Multiplexing (siehe unten) leicht langsamer sein als die Verwendung von zwei oder mehr. Zweitens könnte die Verwendung zu vieler Verbindungen zu einem frühen Paketverlust aufgrund konkurrierender Überlastungssteuerungen führen. Die Verwendung von nur wenigen (aber immer noch mehr als einem) könnte jedoch das Überlastungswachstum mit besserer Leistung ausgleichen, insbesondere in Hochgeschwindigkeitsnetzen. Aus diesen Gründen glaube ich, dass ein bisschen Sharding auch bei HTTP/2 immer noch eine gute Idee ist (z. B. zwei bis vier Verbindungen). Tatsächlich denke ich, dass die meisten modernen HTTP/2-Setups genauso gut funktionieren, weil sie immer noch ein paar zusätzliche Verbindungen oder Lasten von Drittanbietern in ihrem kritischen Pfad haben.
3. Ressourcenbündelung und Inlining
In HTTP/1.1 konnten Sie nur eine einzige aktive Ressource pro Verbindung haben, was zu einer Head-of-Line-Blockierung (HoL) auf HTTP-Ebene führte. Da die Anzahl der Verbindungen auf magere 6 bis 30 begrenzt war, war die Bündelung von Ressourcen (bei der kleinere Unterressourcen zu einer einzigen größeren Ressource kombiniert werden) lange Zeit eine bewährte Methode. Das sehen wir heute noch bei Bundlern wie Webpack. In ähnlicher Weise wurden Ressourcen häufig in andere Ressourcen eingebettet (z. B. wurde kritisches CSS in den HTML-Code eingebettet).
Bei HTTP/2 multiplext jedoch die einzelne Verbindung Ressourcen, sodass Sie viel mehr ausstehende Anfragen für Dateien haben können (anders ausgedrückt, eine einzelne Anfrage belegt nicht länger eine Ihrer wenigen wertvollen Verbindungen). Dies wurde ursprünglich interpretiert als: „ Wir müssen unsere Ressourcen für HTTP/2 nicht mehr bündeln oder einbinden “. Dieser Ansatz wurde als besser für feinkörniges Caching angepriesen, da jede Unterressource einzeln zwischengespeichert werden konnte und das vollständige Paket nicht erneut heruntergeladen werden musste, wenn sich eine von ihnen änderte. Das stimmt, aber nur relativ eingeschränkt.
Beispielsweise könnten Sie die Komprimierungseffizienz verringern, da dies mit mehr Daten besser funktioniert. Darüber hinaus hat jede zusätzliche Anforderung oder Datei einen inhärenten Overhead, da sie vom Browser und Server verarbeitet werden muss. Diese Kosten können sich im Vergleich zu einigen wenigen großen beispielsweise auf Hunderte kleiner Dateien summieren. In unseren eigenen frühen Tests fand ich bei etwa 40 Dateien ernsthaft abnehmende Renditen. Obwohl diese Zahlen jetzt wahrscheinlich etwas höher sind, sind Dateianfragen in HTTP/2 immer noch nicht so billig wie ursprünglich vorhergesagt . Schließlich verursacht das Nicht-Inlining von Ressourcen zusätzliche Latenzkosten, da die Datei angefordert werden muss. Dies, kombiniert mit Priorisierungs- und Server-Push-Problemen (siehe unten), bedeutet, dass Sie sogar heute noch besser dran sind, einige Ihrer kritischen CSS zu inlinen. Vielleicht wird der Vorschlag für Ressourcenpakete eines Tages dabei helfen, aber noch nicht.
All dies gilt natürlich auch weiterhin für HTTP/3. Trotzdem habe ich gelesen, dass Leute behaupten, dass viele kleine Dateien besser wären als QUIC, weil mehr gleichzeitig aktive unabhängige Streams mehr Gewinne aus der Entfernung der HoL-Blockierung bedeuten (wie wir in Teil 2 besprochen haben). Ich denke, daran könnte etwas Wahres sein, aber wie wir auch in Teil 2 gesehen haben, ist dies ein hochkomplexes Thema mit vielen bewegenden Parametern. Ich glaube nicht, dass die Vorteile die anderen diskutierten Kosten überwiegen würden, aber es bedarf weiterer Forschung. (Ein unverschämter Gedanke wäre, jede Datei genau so groß zu haben, dass sie in ein einzelnes QUIC-Paket passt, wodurch die HoL-Blockierung vollständig umgangen wird. Ich werde Lizenzgebühren von jedem Startup akzeptieren, das einen Ressourcenbündelr implementiert, der dies tut. ;))
4. Priorisierung
Um mehrere Dateien über eine einzige Verbindung herunterladen zu können, müssen Sie sie irgendwie multiplexen. Wie in Teil 2 besprochen, wird dieses Multiplexing in HTTP/2 über sein Priorisierungssystem gesteuert. Aus diesem Grund ist es wichtig, dass so viele Ressourcen wie möglich auf derselben Verbindung angefordert werden – um sie untereinander richtig priorisieren zu können! Wie wir auch gesehen haben, war dieses System jedoch sehr komplex , was dazu führte, dass es in der Praxis oft schlecht verwendet und implementiert wurde (siehe Abbildung unten). Dies wiederum hat dazu geführt, dass einige andere Empfehlungen für HTTP/2 – wie z. B. reduzierte Bündelung, weil Anfragen billig sind, und reduziertes Server-Sharding, um die einzelne Verbindung optimal zu nutzen (siehe oben) – sich als unterdurchschnittlich erwiesen haben üben.
Leider können Sie als durchschnittlicher Webentwickler nicht viel dagegen tun, da es hauptsächlich ein Problem in den Browsern und Servern selbst ist. Sie können jedoch versuchen, das Problem zu entschärfen, indem Sie nicht zu viele einzelne Dateien verwenden (was die Wahrscheinlichkeit konkurrierender Prioritäten verringert) und weiterhin (begrenztes) Sharding verwenden. Eine weitere Option ist die Verwendung verschiedener prioritätsbeeinflussender Techniken wie Lazy Loading, JavaScript async
und defer
und Ressourcenhinweise wie preload
. Intern ändern diese hauptsächlich die Prioritäten der Ressourcen, sodass sie früher oder später gesendet werden. Allerdings können (und tun) diese Mechanismen unter Fehlern leiden. Erwarten Sie außerdem nicht, einen preload
Ressourcen vorab zu laden und die Dinge schneller zu machen: Wenn plötzlich alles eine hohe Priorität hat, dann nichts! Es ist sogar sehr einfach, tatsächlich kritische Ressourcen zu verzögern, indem Sie Dinge wie preload
verwenden.
Wie auch in Teil 2 erläutert, verändert HTTP/3 die Interna dieses Priorisierungssystems grundlegend. Wir hoffen , dass dies bedeutet, dass es viel weniger Fehler und Probleme bei der praktischen Bereitstellung geben wird, also sollten zumindest einige davon gelöst werden. Wir können uns jedoch noch nicht sicher sein, da heute nur wenige HTTP/3-Server und -Clients dieses System vollständig implementieren. Dennoch werden sich die grundlegenden Konzepte der Priorisierung nicht ändern . Sie werden immer noch nicht in der Lage sein, Techniken wie das preload
zu verwenden, ohne wirklich zu verstehen, was intern passiert, weil es Ihre Ressourcen immer noch falsch priorisieren könnte.
5. Server-Push und Erstflug
Server-Push ermöglicht es einem Server, Antwortdaten zu senden, ohne zuerst auf eine Anfrage vom Client zu warten. Auch dies klingt theoretisch großartig und könnte anstelle von Inlining-Ressourcen verwendet werden (siehe oben). Wie in Teil 2 besprochen, ist Push jedoch aufgrund von Problemen mit Überlastungskontrolle, Caching, Priorisierung und Pufferung sehr schwierig richtig zu verwenden. Insgesamt ist es am besten, es nicht für das allgemeine Laden von Webseiten zu verwenden, es sei denn, Sie wissen wirklich , was Sie tun, und selbst dann wäre es wahrscheinlich eine Mikrooptimierung. Ich glaube jedoch immer noch, dass es einen Platz mit (REST)-APIs haben könnte, wo Sie Unterressourcen, die in der (JSON)-Antwort verlinkt sind, auf eine aufgewärmte Verbindung übertragen können. Dies gilt sowohl für HTTP/2 als auch für HTTP/3.
Um es ein wenig zu verallgemeinern, denke ich, dass ähnliche Bemerkungen für die TLS-Sitzungswiederaufnahme und 0-RTT gemacht werden könnten, sei es über TCP + TLS oder über QUIC. Wie in Teil 2 besprochen, ähnelt 0-RTT dem Server-Push (wie es normalerweise verwendet wird) insofern, als es versucht, die allerersten Phasen des Ladens einer Seite zu beschleunigen. Das bedeutet jedoch, dass es zu diesem Zeitpunkt ebenso begrenzt ist, was es erreichen kann (noch mehr in QUIC, aufgrund von Sicherheitsbedenken). Daher ist eine Mikrooptimierung wiederum eine Art Feinabstimmung auf niedriger Ebene, um wirklich davon zu profitieren. Und wenn ich bedenke, dass ich einmal sehr aufgeregt war, die Kombination von Server-Push mit 0-RTT auszuprobieren.
Was soll das alles heißen?
All dies lässt sich auf eine einfache Faustregel reduzieren: Wenden Sie die meisten der typischen HTTP/2-Empfehlungen an, die Sie online finden, aber übertreiben Sie es nicht .
Hier sind einige konkrete Punkte, die hauptsächlich für HTTP/2 und HTTP/3 gelten:
- Teilen Sie Ressourcen über etwa ein bis drei Verbindungen auf dem kritischen Pfad (es sei denn, Ihre Benutzer befinden sich hauptsächlich in Netzwerken mit geringer Bandbreite) und verwenden Sie bei Bedarf
preconnect
und DNSdns-prefetch
. - Bündeln Sie Unterressourcen logisch pro Pfad oder Feature oder pro Änderungshäufigkeit. Fünf bis zehn JavaScript- und fünf bis zehn CSS-Ressourcen pro Seite sollten in Ordnung sein. Das Inlining von kritischem CSS kann immer noch eine gute Optimierung sein.
- Verwenden Sie komplexe Funktionen wie
preload
sparsam. - Verwenden Sie einen Server, der die HTTP/2-Priorisierung ordnungsgemäß unterstützt. Für HTTP/2 empfehle ich H2O. Apache und NGINX sind meistens OK (könnten aber besser sein), während Node.js für HTTP/2 zu vermeiden ist. Für HTTP/3 sind die Dinge derzeit weniger klar (siehe unten).
- Stellen Sie sicher, dass TLS 1.3 auf Ihrem HTTP/2-Webserver aktiviert ist.
Wie Sie sehen können, ist die Optimierung von Seiten für HTTP/3 (und HTTP/2) zwar alles andere als einfach, aber kein Hexenwerk. Schwieriger wird es allerdings, HTTP/3-Server, -Clients und -Tools richtig einzurichten.
Server und Netzwerke
Wie Sie wahrscheinlich bereits verstanden haben, sind QUIC und HTTP/3 recht komplexe Protokolle. Sie von Grund auf neu zu implementieren, würde das Lesen (und Verstehen!) Hunderter von Seiten erfordern, die über mehr als sieben Dokumente verteilt sind. Glücklicherweise arbeiten mehrere Unternehmen seit über fünf Jahren an Open-Source-QUIC- und HTTP/3-Implementierungen, sodass wir mehrere ausgereifte und stabile Optionen zur Auswahl haben.
Einige der wichtigsten und stabilsten sind die folgenden:
Sprache | Implementierung |
---|---|
Python | aioqui |
gehen | schnell los |
Rost | Quiche (Cloudflare), Quinn, Neqo (Mozilla) |
C und C++ | mvfst (Facebook), MsQuic, (Microsoft), (Google), ngtcp2, LSQUIC (Litespeed), picoquic, quicly (schnell) |
Viele (vielleicht die meisten) dieser Implementierungen kümmern sich jedoch hauptsächlich um das HTTP/3- und QUIC-Zeug; Sie sind an sich keine wirklich vollwertigen Webserver . Wenn es um Ihre typischen Server geht (denken Sie an NGINX, Apache, Node.js), waren die Dinge aus mehreren Gründen etwas langsamer. Erstens waren nur wenige ihrer Entwickler von Anfang an mit HTTP/3 beschäftigt, und jetzt müssen sie aufholen. Viele umgehen dies, indem sie eine der oben aufgeführten Implementierungen intern als Bibliotheken verwenden, aber selbst diese Integration ist schwierig.
Zweitens hängen viele Server von TLS-Bibliotheken von Drittanbietern wie OpenSSL ab. Dies liegt wiederum daran, dass TLS sehr komplex ist und sicher sein muss, sodass es am besten ist, vorhandene, verifizierte Arbeit wiederzuverwenden. Obwohl QUIC in TLS 1.3 integriert ist, verwendet es es auf eine Weise, die sich stark von der Interaktion von TLS und TCP unterscheidet . Das bedeutet, dass TLS-Bibliotheken QUIC-spezifische APIs bereitstellen müssen, was ihre Entwickler lange Zeit zurückhaltend oder langsam getan haben. Hier geht es insbesondere um OpenSSL, das die QUIC-Unterstützung verschoben hat, aber auch von vielen Servern verwendet wird. Dieses Problem wurde so schlimm, dass Akamai beschloss, einen QUIC-spezifischen Fork von OpenSSL namens quictls zu starten. Während andere Optionen und Problemumgehungen existieren, ist die TLS 1.3-Unterstützung für QUIC immer noch ein Blocker für viele Server, und es wird erwartet, dass dies noch einige Zeit so bleiben wird.
Es folgt eine unvollständige Liste vollständiger Webserver, die Sie sofort verwenden können sollten, zusammen mit ihrer aktuellen HTTP/3-Unterstützung:
- Apache
Die Unterstützung ist derzeit unklar. Es wurde nichts angekündigt. Es benötigt wahrscheinlich auch OpenSSL. (Beachten Sie jedoch, dass es eine Apache Traffic Server-Implementierung gibt.) - NGINX
Dies ist eine benutzerdefinierte Implementierung. Dies ist relativ neu und noch sehr experimentell. Es wird erwartet, dass es bis Ende 2021 mit dem Mainline-NGINX zusammengeführt wird. Dies ist relativ neu und noch sehr experimentell. Beachten Sie, dass es einen Patch gibt, um die Quiche-Bibliothek von Cloudflare auch auf NGINX auszuführen, der derzeit wahrscheinlich stabiler ist. - Node.js
Dies verwendet intern die ngtcp2-Bibliothek. Es wird durch den OpenSSL-Fortschritt blockiert, obwohl sie planen, zum QUIC-TLS-Fork zu wechseln, um etwas früher zum Laufen zu bringen. - IIS
Die Unterstützung ist derzeit unklar, und es wurde nichts angekündigt. Es wird jedoch wahrscheinlich die MsQuic-Bibliothek intern verwenden. - Hyperkorn
Diese integriert aioquic, mit experimenteller Unterstützung. - Caddie
Dies verwendet Quic-Go, mit voller Unterstützung. - H2O
Dies nutzt schnell, mit voller Unterstützung. - Litespeed
Dies verwendet LSQUIC mit voller Unterstützung.
Beachten Sie einige wichtige Nuancen:
- Auch „volle Unterstützung“ bedeutet „so gut wie es im Moment geht“, nicht unbedingt „produktionsreif“. Beispielsweise unterstützen viele Implementierungen Verbindungsmigration, 0-RTT, Server-Push oder HTTP/3-Priorisierung noch nicht vollständig .
- Andere nicht aufgeführte Server wie Tomcat haben (meines Wissens nach) noch keine Ankündigung gemacht.
- Von den aufgeführten Webservern wurden nur Litespeed, der NGINX-Patch von Cloudflare und H2O von Personen entwickelt, die eng mit der QUIC- und HTTP/3-Standardisierung befasst sind, sodass diese höchstwahrscheinlich früh am besten funktionieren.
Wie Sie sehen, ist die Serverlandschaft noch nicht vollständig, aber es gibt sicherlich schon Möglichkeiten, einen HTTP/3-Server einzurichten. Das einfache Ausführen des Servers ist jedoch nur der erste Schritt. Es und den Rest Ihres Netzwerks zu konfigurieren ist schwieriger.
Netzwerkkonfiguration
Wie in Teil 1 erläutert, läuft QUIC auf dem UDP-Protokoll, um die Bereitstellung zu vereinfachen. Dies bedeutet jedoch hauptsächlich, dass die meisten Netzwerkgeräte UDP analysieren und verstehen können. Leider bedeutet dies nicht, dass UDP allgemein erlaubt ist . Da UDP häufig für Angriffe verwendet wird und für den normalen Arbeitsalltag neben DNS unkritisch ist, blockieren viele (Unternehmens-)Netzwerke und Firewalls das Protokoll fast vollständig. Daher muss UDP wahrscheinlich explizit von/zu Ihren HTTP/3-Servern zugelassen werden . QUIC kann auf jedem UDP-Port ausgeführt werden, aber erwarten Sie, dass Port 443 (der normalerweise auch für HTTPS über TCP verwendet wird) am häufigsten verwendet wird.
Viele Netzwerkadministratoren werden jedoch UDP-Wholesale nicht einfach zulassen wollen. Stattdessen werden sie ausdrücklich QUIC über UDP zulassen wollen. Das Problem dabei ist, dass QUIC, wie wir gesehen haben, fast vollständig verschlüsselt ist. Dazu gehören Metadaten auf QUIC-Ebene wie Paketnummern, aber beispielsweise auch Signale, die den Verbindungsabbau anzeigen. Bei TCP verfolgen Firewalls aktiv alle diese Metadaten, um das erwartete Verhalten zu überprüfen. (Haben wir einen vollständigen Handshake vor datentragenden Paketen gesehen? Folgen die Pakete den erwarteten Mustern? Wie viele offene Verbindungen gibt es?) Wie wir in Teil 1 gesehen haben, ist dies genau einer der Gründe, warum TCP nicht mehr praktisch weiterentwickelt werden kann. Aufgrund der Verschlüsselung von QUIC können Firewalls jedoch viel weniger von dieser Verfolgungslogik auf Verbindungsebene ausführen , und die wenigen Bits, die sie untersuchen können , sind relativ komplex.
Daher empfehlen viele Firewall-Anbieter derzeit, QUIC zu blockieren, bis sie ihre Software aktualisieren können. Auch danach möchten viele Unternehmen dies möglicherweise nicht zulassen, da die Firewall-QUIC-Unterstützung immer viel geringer sein wird als die TCP-Funktionen, an die sie gewöhnt sind.
Dies alles wird durch die Verbindungsmigrationsfunktion noch komplizierter. Wie wir gesehen haben, ermöglicht diese Funktion, dass die Verbindung von einer neuen IP-Adresse fortgesetzt wird, ohne dass ein neuer Handshake durchgeführt werden muss, indem Verbindungs-IDs (CIDs) verwendet werden. Für die Firewall sieht dies jedoch so aus, als würde eine neue Verbindung verwendet, ohne zuerst einen Handshake zu verwenden, was genauso gut ein Angreifer sein könnte, der böswilligen Datenverkehr sendet. Firewalls können nicht nur die QUIC-CIDs verwenden, da sie sich auch im Laufe der Zeit ändern, um die Privatsphäre der Benutzer zu schützen! Daher müssen die Server mit der Firewall darüber kommunizieren, welche CIDs erwartet werden , aber nichts davon existiert noch.
Ähnliche Bedenken gibt es bei Load Balancern für größere Setups. Diese Maschinen verteilen eingehende Verbindungen auf eine große Anzahl von Backend-Servern. Der Datenverkehr für eine Verbindung muss natürlich immer an denselben Backend-Server geleitet werden (die anderen wüssten nichts damit anzufangen!). Für TCP könnte dies einfach auf der Grundlage des 4-Tupels erfolgen, da sich das nie ändert. Mit der QUIC-Verbindungsmigration ist das jedoch keine Option mehr. Auch hier müssen sich Server und Load Balancer irgendwie darauf einigen, welche CIDs gewählt werden sollen, um deterministisches Routing zu ermöglichen . Anders als bei der Firewall-Konfiguration gibt es aber bereits einen Vorschlag, diese einzurichten (allerdings noch lange nicht flächendeckend umgesetzt).
Schließlich gibt es noch andere Sicherheitsüberlegungen auf höherer Ebene, hauptsächlich in Bezug auf 0-RTT- und Distributed-Denial-of-Service-Angriffe (DDoS). Wie in Teil 2 besprochen, enthält QUIC bereits einige Abwehrmaßnahmen für diese Probleme, aber idealerweise werden sie auch zusätzliche Verteidigungslinien im Netzwerk verwenden. Beispielsweise können Proxy- oder Edge-Server bestimmte 0-RTT-Anforderungen daran hindern, die eigentlichen Back-Ends zu erreichen, um Replay-Angriffe zu verhindern. Um Reflexionsangriffe oder DDoS-Angriffe zu verhindern, die nur das erste Handshake-Paket senden und dann nicht mehr antworten (in TCP als SYN-Flood bezeichnet), enthält QUIC alternativ die Wiederholungsfunktion. Dadurch kann der Server überprüfen, ob es sich um einen gut erzogenen Client handelt, ohne dass er in der Zwischenzeit irgendeinen Status beibehalten muss (das Äquivalent zu TCP-SYN-Cookies). Dieser Wiederholungsprozess findet natürlich am besten irgendwo vor dem Backend-Server statt – zum Beispiel beim Load Balancer. Auch dies erfordert jedoch eine zusätzliche Konfiguration und Kommunikation, um eingerichtet zu werden.
Dies sind nur die wichtigsten Probleme, die Netzwerk- und Systemadministratoren mit QUIC und HTTP/3 haben werden. Es gibt noch einige mehr, von denen ich einige erwähnt habe. Es gibt auch zwei separate Begleitdokumente für die QUIC-RFCs, die diese Probleme und ihre möglichen (teilweisen) Minderungen erörtern.
Was soll das alles heißen?
HTTP/3 und QUIC sind komplexe Protokolle, die auf vielen internen Maschinen beruhen. All das ist noch nicht bereit für die Hauptsendezeit , obwohl Sie bereits einige Optionen haben, um die neuen Protokolle auf Ihren Backends bereitzustellen. Es wird jedoch wahrscheinlich einige Monate bis sogar Jahre dauern, bis die bekanntesten Server und zugrunde liegenden Bibliotheken (wie OpenSSL) aktualisiert werden.
Selbst dann wird es in größeren Setups nicht trivial sein, die Server und andere Netzwerkvermittler richtig zu konfigurieren, damit die Protokolle sicher und optimal verwendet werden können. Sie benötigen ein gutes Entwicklungs- und Betriebsteam, um diesen Übergang korrekt durchzuführen.
Daher ist es besonders in der Anfangszeit wahrscheinlich am besten, sich auf ein großes Hosting-Unternehmen oder CDN zu verlassen, um die Protokolle für Sie einzurichten und zu konfigurieren. Wie in Teil 2 besprochen, zahlt sich QUIC dort sowieso am ehesten aus, und die Verwendung eines CDN ist eine der wichtigsten Leistungsoptimierungen, die Sie vornehmen können. Ich persönlich würde die Verwendung von Cloudflare oder Fastly empfehlen, da sie eng in den Standardisierungsprozess involviert waren und über die fortschrittlichsten und am besten abgestimmten Implementierungen verfügen werden.
Kunden und QUIC Discovery
Bisher haben wir serverseitige und netzwerkinterne Unterstützung für die neuen Protokolle berücksichtigt. Aber auch auf Kundenseite sind einige Probleme zu lösen.
Bevor wir dazu kommen, fangen wir mit einer guten Nachricht an: Die meisten gängigen Browser unterstützen bereits (experimentell) HTTP/3! Zum Zeitpunkt des Schreibens ist hier insbesondere der Status des Supports (siehe auch caniuse.com):
- Google Chrome (Version 91+) : Standardmäßig aktiviert.
- Mozilla Firefox (Version 89+) : Standardmäßig aktiviert.
- Microsoft Edge (Version 90+) : Standardmäßig aktiviert (verwendet Chromium intern).
- Opera (Version 77+) : Standardmäßig aktiviert (verwendet Chromium intern).
- Apple Safari (Version 14) : Hinter einer manuellen Flagge. Wird standardmäßig in Version 15 aktiviert, die sich derzeit in der Technologievorschau befindet.
- Andere Browser : Mir sind noch keine Signale bekannt (obwohl andere Browser, die Chromium intern verwenden, wie z. B. Brave, theoretisch auch damit beginnen könnten, es zu aktivieren).
Beachten Sie einige Nuancen:
- Die meisten Browser werden schrittweise eingeführt, wobei nicht alle Benutzer die HTTP/3-Unterstützung von Anfang an aktiviert bekommen. Dies geschieht, um das Risiko zu begrenzen, dass ein einzelner übersehener Fehler viele Benutzer betreffen könnte oder dass Serverbereitstellungen überlastet werden. Daher besteht eine geringe Chance, dass Sie selbst in neueren Browserversionen HTTP/3 nicht standardmäßig erhalten und es manuell aktivieren müssen.
- Wie bei den Servern bedeutet die HTTP/3-Unterstützung nicht, dass alle Funktionen implementiert sind oder derzeit verwendet werden. Insbesondere 0-RTT, Verbindungsmigration, Server-Push, dynamische QPACK-Header-Komprimierung und HTTP/3-Priorisierung könnten immer noch fehlen, deaktiviert, sparsam verwendet oder schlecht konfiguriert sein.
- Wenn Sie clientseitiges HTTP/3 außerhalb des Browsers verwenden möchten (z. B. in Ihrer nativen App), müssen Sie eine der oben aufgeführten Bibliotheken integrieren oder cURL verwenden. Apple wird bald native HTTP/3- und QUIC-Unterstützung in seine integrierten Netzwerkbibliotheken auf macOS und iOS bringen, und Microsoft fügt QUIC zum Windows-Kernel und seiner .NET-Umgebung hinzu, aber eine ähnliche native Unterstützung gab es (meines Wissens nach) nicht für andere Systeme wie Android angekündigt.
Alt-Svc
Selbst wenn Sie einen HTTP/3-kompatiblen Server eingerichtet haben und einen aktualisierten Browser verwenden, werden Sie möglicherweise überrascht sein, dass HTTP/3 nicht wirklich konsequent verwendet wird . Um zu verstehen, warum, nehmen wir an, Sie sind für einen Moment der Browser. Ihr Benutzer hat Sie aufgefordert, zu example.com
zu navigieren (eine Website, die Sie noch nie zuvor besucht haben), und Sie haben DNS verwendet, um dies in eine IP aufzulösen. Sie senden ein oder mehrere QUIC-Handshake-Pakete an diese IP. Jetzt kann einiges schief gehen:
- Der Server unterstützt möglicherweise QUIC nicht.
- Eines der zwischengeschalteten Netzwerke oder Firewalls könnte QUIC und/oder UDP vollständig blockieren.
- Die Handshake-Pakete können während der Übertragung verloren gehen.
Wie würden Sie jedoch wissen, (welches) eines dieser Probleme aufgetreten ist ? In allen drei Fällen erhalten Sie niemals eine Antwort auf Ihr(e) Handshake-Paket(e). Das einzige, was Sie tun können, ist zu warten und zu hoffen, dass vielleicht doch noch eine Antwort eintrifft. Dann könnten Sie nach einer gewissen Wartezeit (dem Timeout) entscheiden, dass tatsächlich ein Problem mit HTTP/3 vorliegt. An diesem Punkt würden Sie versuchen, eine TCP-Verbindung zum Server herzustellen, in der Hoffnung, dass HTTP/2 oder HTTP/1.1 funktionieren.
Wie Sie sehen können, könnte diese Art von Ansatz zu erheblichen Verzögerungen führen, insbesondere in den ersten Jahren, in denen viele Server und Netzwerke QUIC noch nicht unterstützen. Eine einfache, aber naive Lösung wäre, einfach eine QUIC- und eine TCP-Verbindung gleichzeitig zu öffnen und dann den Handshake zu verwenden, der zuerst abgeschlossen wird . Diese Methode nennt sich „Connection Racing“ oder „Happy Eyeballs“. Dies ist zwar durchaus möglich, jedoch mit erheblichem Overhead verbunden. Auch wenn die verlorene Verbindung fast sofort geschlossen wird, nimmt sie dennoch etwas Speicher und CPU-Zeit sowohl auf dem Client als auch auf dem Server in Anspruch (insbesondere bei Verwendung von TLS). Darüber hinaus gibt es noch andere Probleme mit dieser Methode im Zusammenhang mit IPv4- versus IPv6-Netzwerken und den zuvor diskutierten Replay-Angriffen (auf die mein Vortrag ausführlicher eingeht).
Daher würden Browser bei QUIC und HTTP/3 lieber auf Nummer sicher gehen und QUIC nur ausprobieren, wenn sie wissen, dass der Server es unterstützt . Daher verwendet der Browser beim ersten Kontakt mit einem neuen Server nur HTTP/2 oder HTTP/1.1 über eine TCP-Verbindung. Der Server kann dann dem Browser mitteilen, dass er auch HTTP/3 für nachfolgende Verbindungen unterstützt. Dies geschieht durch Setzen eines speziellen HTTP-Headers auf die über HTTP/2 oder HTTP/1.1 zurückgesendeten Antworten. Dieser Header heißt Alt-Svc
, was für „alternative services“ steht. Alt-Svc
kann verwendet werden, um einem Browser mitzuteilen, dass ein bestimmter Dienst auch über einen anderen Server (IP und/oder Port) erreichbar ist, aber es ermöglicht auch die Angabe alternativer Protokolle. Dies ist unten in Abbildung 1 zu sehen.
Beim Empfang eines gültigen Alt-Svc
Headers, der HTTP/3-Unterstützung anzeigt, wird der Browser diesen zwischenspeichern und von da an versuchen, eine QUIC-Verbindung aufzubauen. Einige Clients tun dies so schnell wie möglich (sogar während des anfänglichen Ladens der Seite – siehe unten), während andere warten, bis die bestehende(n) TCP-Verbindung(en) geschlossen werden. Dies bedeutet, dass der Browser HTTP/3 immer nur dann verwendet, wenn er zuvor mindestens einige Ressourcen über HTTP/2 oder HTTP/1.1 heruntergeladen hat . Selbst dann ist es kein glattes Segeln. Der Browser weiß jetzt, dass der Server HTTP/3 unterstützt, aber das bedeutet nicht, dass das zwischengeschaltete Netzwerk ihn nicht blockiert. Daher wird in der Praxis nach wie vor Connection Racing benötigt. Sie könnten also immer noch bei HTTP/2 landen, wenn das Netzwerk den QUIC-Handshake irgendwie genug verzögert. Wenn die QUIC-Verbindung einige Male hintereinander nicht hergestellt werden kann, setzen einige Browser den Alt-Svc
Cache-Eintrag für einige Zeit auf eine Denylist und versuchen HTTP/3 für eine Weile nicht. Daher kann es hilfreich sein, den Cache Ihres Browsers manuell zu löschen, wenn die Dinge nicht funktionieren, da dies auch die Alt-Svc
Bindungen leeren sollte. Schließlich hat sich gezeigt, dass Alt-Svc
einige ernsthafte Sicherheitsrisiken birgt. Aus diesem Grund stellen einige Browser beispielsweise zusätzliche Einschränkungen hinsichtlich der verwendbaren Ports auf (in Chrome müssen Ihre HTTP/2- und HTTP/3-Server entweder beide auf einem Port unter 1024 oder beide auf einem Port über oder gleich sein bis 1024, ansonsten wird Alt-Svc
ignoriert). All diese Logik variiert und entwickelt sich wild zwischen den Browsern, was bedeutet, dass es schwierig sein kann, konsistente HTTP/3-Verbindungen zu erhalten, was es auch schwierig macht, neue Setups zu testen.
Es wird laufend daran gearbeitet, diesen zweistufigenAlt-Svc
Prozess etwas zu verbessern. Die Idee ist, neue DNS-Einträge namens SVCB und HTTPS zu verwenden, die ähnliche Informationen wie inAlt-Svc
. Als solches kann der Client feststellen, dass ein Server stattdessen HTTP/3 während des DNS-Auflösungsschritts unterstützt, was bedeutet, dass er QUIC vom allerersten Seitenladen an ausprobieren kann, anstatt zuerst HTTP/2 oder HTTP/1.1 durchlaufen zu müssen. Weitere Informationen dazu und zuAlt-Svc
finden Sie im letztjährigen Web Almanac-Kapitel zu HTTP/2.
Wie Sie sehen können, Alt-Svc
und der HTTP/3-Erkennungsprozess Ihrer ohnehin schon herausfordernden QUIC-Serverbereitstellung eine Ebene der Komplexität hinzu, weil:
- Sie müssen Ihren HTTP/3-Server immer neben einem HTTP/2- und/oder HTTP/1.1-Server bereitstellen;
- Sie müssen Ihre HTTP/2- und HTTP/1.1-Server konfigurieren, um die richtigen
Alt-Svc
Header für ihre Antworten festzulegen.
Während dies in Setups auf Produktionsebene überschaubar sein sollte (weil beispielsweise eine einzelne Apache- oder NGINX-Instanz wahrscheinlich alle drei HTTP-Versionen gleichzeitig unterstützt), kann es in (lokalen) Testumgebungen viel ärgerlicher sein. ups (ich kann mich schon sehen, wie ich vergesse, die Alt-Svc
Header hinzuzufügen oder sie durcheinander zu bringen). Dieses Problem wird durch einen (aktuellen) Mangel an Browser-Fehlerprotokollen und DevTools-Indikatoren verstärkt, was bedeutet, dass es schwierig sein kann, herauszufinden, warum genau das Setup nicht funktioniert.
Zusätzliche Probleme
Als ob das nicht genug wäre, erschwert ein weiteres Problem das lokale Testen: Chrome macht es Ihnen sehr schwer, selbstsignierte TLS-Zertifikate für QUIC zu verwenden . Dies liegt daran, dass Unternehmen häufig nicht offizielle TLS-Zertifikate verwenden, um den TLS-Verkehr ihrer Mitarbeiter zu entschlüsseln (damit sie beispielsweise verschlüsselten Verkehr von ihrer Firewall scannen lassen können). Wenn Unternehmen dies jedoch mit QUIC tun würden, hätten wir wieder benutzerdefinierte Middlebox-Implementierungen, die ihre eigenen Annahmen über das Protokoll treffen. Dies könnte dazu führen, dass sie in Zukunft möglicherweise die Protokollunterstützung brechen, und genau das haben wir versucht zu verhindern, indem wir QUIC von Anfang an so umfassend verschlüsselt haben! As such, Chrome takes a very opinionated stance on this: If you're not using an official TLS certificate (signed by a certificate authority or root certificate that is trusted by Chrome, such as Let's Encrypt), then you cannot use QUIC . This, sadly, also includes self-signed certificates, which are often used for local test set-ups.
It is still possible to bypass this with some freaky command-line flags (because the common --ignore-certificate-errors
doesn't work for QUIC yet), by using per-developer certificates (although setting this up can be tedious), or by setting up the real certificate on your development PC (but this is rarely an option for big teams because you would have to share the certificate's private key with each developer). Finally, while you can install a custom root certificate, you would then also need to pass both the --origin-to-force-quic-on
and --ignore-certificate-errors-spki-list
flags when starting Chrome (see below). Luckily, for now, only Chrome is being so strict, and hopefully, its developers will loosen their approach over time.
If you are having problems with your QUIC set-up from inside a browser, it's best to first validate it using a tool such as cURL. cURL has excellent HTTP/3 support (you can even choose between two different underlying libraries) and also makes it easier to observe Alt-Svc
caching logic.
Was soll das alles heißen?
Next to the challenges involved with setting up HTTP/3 and QUIC on the server-side, there are also difficulties in getting browsers to use the new protocols consistently. This is due to a two-step discovery process involving the Alt-Svc
HTTP header and the fact that HTTP/2 connections cannot simply be “upgraded” to HTTP/3, because the latter uses UDP.
Even if a server supports HTTP/3, however, clients (and website owners!) need to deal with the fact that intermediate networks might block UDP and/or QUIC traffic. As such, HTTP/3 will never completely replace HTTP/2 . In practice, keeping a well-tuned HTTP/2 set-up will remain necessary both for first-time visitors and visitors on non-permissive networks. Luckily, as we discussed, there shouldn't be many page-level changes between HTTP/2 and HTTP/3, so this shouldn't be a major headache.
What could become a problem, however, is testing and verifying whether you are using the correct configuration and whether the protocols are being used as expected. This is true in production, but especially in local set-ups. As such, I expect that most people will continue to run HTTP/2 (or even HTTP/1.1) development servers , switching only to HTTP/3 in a later deployment stage. Even then, however, validating protocol performance with the current generation of tools won't be easy.
Tools and Testing
As was the case with many major servers, the makers of the most popular web performance testing tools have not been keeping up with HTTP/3 from the start. Consequently, few tools have dedicated support for the new protocol as of July 2021, although they support it to a certain degree.
Google Leuchtturm
First, there is the Google Lighthouse tool suite. While this is an amazing tool for web performance in general, I have always found it somewhat lacking in aspects of protocol performance. This is mostly because it simulates slow networks in a relatively unrealistic way, in the browser (the same way that Chrome's DevTools handle this). While this approach is quite usable and typically “good enough” to get an idea of the impact of a slow network, testing low-level protocol differences is not realistic enough. Because the browser doesn't have direct access to the TCP stack, it still downloads the page on your normal network, and it then artificially delays the data from reaching the necessary browser logic. This means, for example, that Lighthouse emulates only delay and bandwidth, but not packet loss (which, as we've seen, is a major point where HTTP/3 could potentially differ from HTTP/2). Alternatively, Lighthouse uses a highly advanced simulation model to guesstimate the real network impact, because, for example, Google Chrome has some complex logic that tweaks several aspects of a page load if it detects a slow network. This model has, to the best of my knowledge, not been adjusted to handle IETF QUIC or HTTP/3 yet. As such, if you use Lighthouse today for the sole purpose of comparing HTTP/2 and HTTP/3 performance, then you are likely to get erroneous or oversimplified results, which could lead you to wrong conclusions about what HTTP/3 can do for your website in practice. The silver lining is that, in theory, this can be improved massively in the future, because the browser does have full access to the QUIC stack, and thus Lighthouse could add much more advanced simulations (including packet loss!) for HTTP/3 down the line. For now, though, while Lighthouse can, in theory, load pages over HTTP/3, I would recommend against it.
WebPageTest
Secondly, there is WebPageTest. This amazing project lets you load pages over real networks from real devices across the world, and it also allows you to add packet-level network emulation on top, including aspects such as packet loss! As such, WebPageTest is conceptually in a prime position to be used to compare HTTP/2 and HTTP/3 performance. However, while it can indeed already load pages over the new protocol, HTTP/3 has not yet been properly integrated into the tooling or visualizations . For example, there are currently no easy ways to force a page load over QUIC, to easily view how Alt-Svc
was actually used, or even to see QUIC handshake details. In some cases, even seeing whether a response used HTTP/3 or HTTP/2 can be challenging. Still, in April, I was able to use WebPageTest to run quite a few tests on facebook.com
and see HTTP/3 in action, which I'll go over now.
First, I ran a default test for facebook.com
, enabling the “repeat view” option. As explained above, I would expect the first page load to use HTTP/2, which will include the Alt-Svc
response header. As such, the repeat view should use HTTP/3 from the start. In Firefox version 89, this is more or less what happens. However, when looking at individual responses, we see that even during the first page load, Firefox will switch to using HTTP/3 instead of HTTP/2 ! As you can see in figure 2, this happens from the 20th resource onwards. This means that Firefox establishes a new QUIC connection as soon as it sees the Alt-Svc
header, and it switches to it once it succeeds. If you scroll down to the connection view, it also seems to show that Firefox even opened two QUIC connections: one for credentialed CORS requests and one for no-CORS requests. This would be expected because, as we discussed above, even for HTTP/2 and HTTP/3, browsers will open multiple connections due to security concerns. However, because WebPageTest doesn't provide more details in this view, it's difficult to confirm without manually digging through the data. Looking at the repeat view (second visit), it starts by directly using HTTP/3 for the first request, as expected.
Next, for Chrome, we see similar behavior for the first page load, although here Chrome already switches on the 10th resource, much earlier than Firefox. It's a bit more unclear here whether it switches as soon as possible or only when a new connection is needed (for example, for requests with different credentials), because, unlike for Firefox, the connection view also doesn't seem to show multiple QUIC connections. For the repeat view, we see some weirder things. Unexpectedly, Chrome starts off using HTTP/2 there as well , switching to HTTP/3 only after a few requests! I performed a few more tests on other pages as well, to confirm that this is indeed consistent behaviour. This could be due to several things: It might just be Chrome's current policy, it might be that Chrome “raced” a TCP and QUIC connection and TCP won initially, or it might be that the Alt-Svc
cache from the first view was unused for some reason. At this point, there is, sadly, no easy way to determine what the problem really is (and whether it can even be fixed).
Another interesting thing I noticed here is the apparent connection coalescing behavior. As discussed above, both HTTP/2 and HTTP/3 can reuse connections even if they go to other hostnames, to prevent downsides from hostname sharding. However, as shown in figure 3, WebPageTest reports that, for this Facebook load, connection coalescing is used over HTTP/3 forfacebook.com
andfbcdn.net
, but not over HTTP/2 (as Chrome opens a secondary connection for the second domain). I suspect this is a bug in WebPageTest, however, becausefacebook.com
andfbcnd.net
resolve to different IPs and, as such, can't really be coalesced.
The figure also shows that some key QUIC handshake information is missing from the current WebPageTest visualization.
Note : As we see, getting “real” HTTP/3 going can be difficult sometimes. Luckily, for Chrome specifically, we have additional options we can use to test QUIC and HTTP/3, in the form of command-line parameters.
On the bottom of WebPageTest's “Chromium” tab, I used the following command-line options:
--enable-quic --quic-version=h3-29 --origin-to-force-quic-on=www.facebook.com:443,static.xx.fbcdn.net:443
The results from this test show that this indeed forces a QUIC connection from the start, even in the first view, thus bypassing the Alt-Svc
process. Interestingly, you will notice I had to pass two hostnames to --origin-to-force-quic-on
. In the version where I didn't, Chrome, of course, still first opened an HTTP/2 connection to the fbcnd.net
domain, even in the repeat view. As such, you'll need to manually indicate all QUIC origins in order for this to work !
We can see even from these few examples that a lot of stuff is going on with how browsers actually use HTTP/3 in practice. It seems they even switch to the new protocol during the initial page load, abandoning HTTP/2 either as soon as possible or when a new connection is needed. As such, it's difficult not only getting a full HTTP/3 load, but also getting a pure HTTP/2 load on a set-up that supports both ! Because WebPageTest doesn't show much HTTP/3 or QUIC metadata yet, figuring out what's going on can be challenging, and you can't trust the tools and visualizations at face value either.
So, if you use WebPageTest, you'll need to double-check the results to make sure which protocols were actually used. Consequently, I think this means that it's too early to really test HTTP/3 performance at this time (and especially too early to compare it to HTTP/2). This belief is strengthened by the fact that not all servers and clients have implemented all protocol features yet. Due to the fact that WebPageTest doesn't yet have easy ways of showing whether advanced aspects such as 0-RTT were used, it will be tricky to know what you're actually measuring. This is especially true for the HTTP/3 prioritization feature, which isn't implemented properly in all browsers yet and which many servers also lack full support for. Because prioritization can be a major aspect driving web performance, it would be unfair to compare HTTP/3 to HTTP/2 without making sure that at least this feature works properly (for both protocols!). This is just one aspect, though, as my research shows how big the differences between QUIC implementations can be. If you do any comparison of this sort yourself (or if you read articles that do), make 100% sure that you've checked what's actually going on .
Finally, also note that other higher-level tools (or data sets such as the amazing HTTP Archive) are often based on WebPageTest or Lighthouse (or use similar methods), so I suspect that most of my comments here will be widely applicable to most web performance tooling. Even for those tool vendors announcing HTTP/3 support in the coming months, I would be a bit skeptical and would validate that they're actually doing it correctly. For some tools, things are probably even worse, though; for example, Google's PageSpeed Insights only got HTTP/2 support this year, so I wouldn't wait for HTTP/3 arriving anytime soon.
Wireshark, qlog und qvis
Wie die obige Diskussion zeigt, kann es schwierig sein, das HTTP/3-Verhalten an dieser Stelle nur mit Lighthouse oder WebPageTest zu analysieren. Glücklicherweise sind andere Tools auf niedrigerer Ebene verfügbar, um dabei zu helfen. Erstens bietet das ausgezeichnete Wireshark-Tool erweiterte Unterstützung für QUIC und kann auch HTTP/3 experimentell analysieren. Auf diese Weise können Sie beobachten, welche QUIC- und HTTP/3-Pakete tatsächlich über die Leitung gehen. Damit das funktioniert, müssen Sie jedoch die TLS-Entschlüsselungsschlüssel für eine bestimmte Verbindung abrufen, die Sie bei den meisten Implementierungen (einschließlich Chrome und Firefox) mithilfe der Umgebungsvariablen SSLKEYLOGFILE
können. Während dies für einige Dinge nützlich sein kann, kann es eine Menge manueller Arbeit bedeuten, wirklich herauszufinden, was passiert, insbesondere bei längeren Verbindungen. Sie würden auch ein ziemlich fortgeschrittenes Verständnis der inneren Abläufe der Protokolle benötigen.
Glücklicherweise gibt es eine zweite Option, qlog und qvis. qlog ist ein JSON-basiertes Protokollierungsformat speziell für QUIC und HTTP/3, das von den meisten QUIC-Implementierungen unterstützt wird. Anstatt sich die Pakete anzusehen, die über die Leitung gehen, erfasst qlog diese Informationen direkt auf dem Client und Server, was es ihm ermöglicht, einige zusätzliche Informationen (z. B. Details zur Überlastungskontrolle) aufzunehmen. Normalerweise können Sie die qlog-Ausgabe auslösen, wenn Sie Server und Clients mit der Umgebungsvariable QLOGDIR
. (Beachten Sie, dass Sie in Firefox die Einstellung network.http.http3.enable_qlog
festlegen müssen. Apple-Geräte und Safari verwenden stattdessen QUIC_LOG_DIRECTORY
. Chrome unterstützt qlog noch nicht.)
Diese qlog-Dateien können dann in die qvis-Tool-Suite unter qvis.quictools.info hochgeladen werden. Dort erhalten Sie eine Reihe fortschrittlicher interaktiver Visualisierungen, die die Interpretation von QUIC- und HTTP/3-Datenverkehr erleichtern . qvis unterstützt auch das Hochladen von Wireshark-Paketerfassungen ( .pcap
Dateien) und bietet experimentelle Unterstützung für die Netlog-Dateien von Chrome, sodass Sie auch das Verhalten von Chrome analysieren können. Ein vollständiges Tutorial zu qlog und qvis würde den Rahmen dieses Artikels sprengen, aber weitere Details können in Form eines Tutorials, als Papier und sogar im Format einer Talkshow gefunden werden. Sie können mich auch direkt danach fragen, da ich der Hauptimplementierer von qlog und qvis bin. ;)
Ich mache mir jedoch keine Illusionen, dass die meisten Leser hier jemals Wireshark oder qvis verwenden sollten, da dies ziemlich einfache Tools sind. Da wir im Moment jedoch nur wenige Alternativen haben, empfehle ich dringend, die HTTP/3-Leistung nicht ausgiebig zu testen, ohne diese Art von Tool zu verwenden, um sicherzustellen, dass Sie wirklich wissen, was auf der Leitung passiert und ob das, was Sie sehen, wirklich erklärt wird die Interna des Protokolls und nicht durch andere Faktoren.
Was soll das alles heißen?
Wie wir gesehen haben, kann das Einrichten und Verwenden von HTTP/3 über QUIC eine komplexe Angelegenheit sein, und viele Dinge können schief gehen. Leider ist kein gutes Werkzeug oder keine Visualisierung verfügbar, die die notwendigen Details auf einer angemessenen Abstraktionsebene offenlegt. Dies macht es für die meisten Entwickler sehr schwierig, die potenziellen Vorteile zu bewerten, die HTTP/3 zu diesem Zeitpunkt für ihre Website bringen kann, oder sogar zu validieren, ob ihre Einrichtung wie erwartet funktioniert.
Es ist sehr gefährlich, sich nur auf High-Level-Metriken zu verlassen, da diese durch eine Vielzahl von Faktoren verzerrt werden könnten (z. B. unrealistische Netzwerkemulation, fehlende Funktionen auf Clients oder Servern, nur teilweise HTTP/3-Nutzung usw.). Selbst wenn alles besser funktioniert hat, wie wir in Teil 2 gesehen haben, werden die Unterschiede zwischen HTTP/2 und HTTP/3 wahrscheinlich in den meisten Fällen relativ gering sein, was es noch schwieriger macht, die notwendigen Informationen von der High-Level-Ebene zu erhalten Tools ohne gezielte HTTP/3-Unterstützung.
Daher empfehle ich, die Leistungsmessungen von HTTP/2 im Vergleich zu HTTP/3 noch einige Monate in Ruhe zu lassen und sich stattdessen darauf zu konzentrieren, sicherzustellen, dass unsere serverseitigen Setups wie erwartet funktionieren . Dafür ist es am einfachsten, WebPageTest in Kombination mit den Befehlszeilenparametern von Google Chrome zu verwenden, mit einem Fallback auf Curl für potenzielle Probleme – dies ist derzeit die konsistenteste Einrichtung, die ich finden kann.
Fazit und Takeaways
Lieber Leser, wenn Sie die komplette dreiteilige Serie gelesen haben und es hierher geschafft haben, grüße ich Sie ! Auch wenn Sie nur wenige Abschnitte gelesen haben, danke ich Ihnen für Ihr Interesse an diesen neuen und spannenden Protokollen. Jetzt werde ich die wichtigsten Erkenntnisse aus dieser Serie zusammenfassen, einige wichtige Empfehlungen für die kommenden Monate und Jahre geben und Ihnen schließlich einige zusätzliche Ressourcen zur Verfügung stellen, falls Sie mehr wissen möchten.
Zusammenfassung
Zunächst haben wir in Teil 1 besprochen, dass HTTP/3 hauptsächlich wegen des neuen zugrunde liegenden QUIC-Transportprotokolls benötigt wird . QUIC ist der spirituelle Nachfolger von TCP und integriert alle seine Best Practices sowie TLS 1.3. Dies wurde hauptsächlich benötigt, weil TCP aufgrund seiner allgegenwärtigen Bereitstellung und Integration in Middleboxen zu unflexibel geworden ist, um sich weiterzuentwickeln. Die Verwendung von UDP und fast vollständiger Verschlüsselung durch QUIC bedeutet, dass wir (hoffentlich) in Zukunft nur noch die Endpunkte aktualisieren müssen, um neue Funktionen hinzuzufügen, was einfacher sein sollte. QUIC fügt jedoch auch einige interessante neue Funktionen hinzu. Erstens ist der kombinierte Transport- und kryptografische Handshake von QUIC schneller als TCP + TLS und kann die 0-RTT-Funktion gut nutzen. Zweitens weiß QUIC, dass es mehrere unabhängige Byte-Streams trägt, und kann intelligenter damit umgehen, wie es mit Verlusten und Verzögerungen umgeht, wodurch das Problem der Head-of-Line-Blockierung gemildert wird. Drittens können QUIC-Verbindungen Benutzer überleben, die zu einem anderen Netzwerk wechseln (Verbindungsmigration genannt), indem sie jedes Paket mit einer Verbindungs-ID markieren. Schließlich macht die flexible Paketstruktur von QUIC (unter Verwendung von Frames) es effizienter, aber auch flexibler und in der Zukunft erweiterbar. Zusammenfassend ist klar, dass QUIC das Transportprotokoll der nächsten Generation ist und noch viele Jahre verwendet und erweitert wird .
Zweitens haben wir in Teil 2 diese neuen Funktionen etwas kritisch betrachtet, insbesondere ihre Auswirkungen auf die Leistung . Zuerst haben wir gesehen, dass die Verwendung von UDP durch QUIC es nicht auf magische Weise schneller (noch langsamer) macht, da QUIC Überlastungskontrollmechanismen verwendet, die TCP sehr ähnlich sind, um eine Überlastung des Netzwerks zu verhindern. Zweitens sind der schnellere Handshake und 0-RTT eher Mikrooptimierungen, da sie wirklich nur einen Roundtrip schneller sind als ein optimierter TCP + TLS-Stack, und das echte 0-RTT von QUIC wird außerdem durch eine Reihe von Sicherheitsbedenken beeinträchtigt, die einschränken können seine Nützlichkeit. Drittens ist eine Verbindungsmigration wirklich nur in wenigen Einzelfällen erforderlich, und es bedeutet immer noch ein Zurücksetzen der Senderaten, da die Überlastungssteuerung nicht weiß, wie viele Daten das neue Netzwerk verarbeiten kann. Viertens hängt die Effektivität der Head-of-Line-Blocking-Entfernung von QUIC stark davon ab, wie Stream-Daten gemultiplext und priorisiert werden. Ansätze, die optimal zur Wiederherstellung nach Paketverlusten sind, scheinen sich nachteilig auf allgemeine Anwendungsfälle der Ladeleistung von Webseiten und umgekehrt zu auswirken, obwohl weitere Forschung erforderlich ist. Fünftens könnte QUIC beim Senden von Paketen leicht langsamer sein als TCP + TLS, da UDP-APIs weniger ausgereift sind und QUIC jedes Paket einzeln verschlüsselt, obwohl dies mit der Zeit weitgehend abgemildert werden kann. Sechstens bringt HTTP/3 selbst keine großen neuen Leistungsmerkmale auf den Tisch, sondern überarbeitet und vereinfacht hauptsächlich die Interna bekannter HTTP/2-Funktionen. Schließlich sind einige der aufregendsten leistungsbezogenen Funktionen, die QUIC zulässt (Multipath, unzuverlässige Daten, WebTransport, Vorwärtsfehlerkorrektur usw.), nicht Teil der Kernstandards QUIC und HTTP/3, sondern eher vorgeschlagene Erweiterungen, die in Anspruch genommen werden noch etwas Zeit zur Verfügung. Zusammenfassend bedeutet dies, dass QUIC die Leistung für Benutzer in Hochgeschwindigkeitsnetzwerken wahrscheinlich nicht wesentlich verbessern wird, aber hauptsächlich für Benutzer in langsamen und weniger stabilen Netzwerken wichtig sein wird .
Schließlich haben wir uns in diesem Teil 3 angesehen, wie man QUIC und HTTP/3 praktisch verwendet und bereitstellt . Zunächst haben wir gesehen, dass die meisten Best Practices und Erfahrungen aus HTTP/2 einfach auf HTTP/3 übertragen werden sollten. Es besteht keine Notwendigkeit, Ihre Bündelungs- oder Inlining-Strategie zu ändern oder Ihre Serverfarm zu konsolidieren oder zu fragmentieren. Server-Push ist immer noch nicht die beste Funktion, und preload
kann ebenfalls ein mächtiges Fußgewehr sein. Zweitens haben wir besprochen, dass es eine Weile dauern kann, bis Standard-Webserverpakete vollständige HTTP/3-Unterstützung bieten (teilweise aufgrund von Problemen mit der Unterstützung von TLS-Bibliotheken), obwohl viele Open-Source-Optionen für Early Adopters und verfügbar sind Mehrere große CDNs haben ein ausgereiftes Angebot. Drittens ist klar, dass die meisten gängigen Browser (grundlegende) HTTP/3-Unterstützung haben, die sogar standardmäßig aktiviert ist. Es gibt jedoch große Unterschiede darin, wie und wann sie HTTP/3 und seine neuen Funktionen praktisch verwenden, sodass es schwierig sein kann, ihr Verhalten zu verstehen. Viertens haben wir besprochen, dass dies durch einen Mangel an expliziter HTTP/3-Unterstützung in populären Tools wie Lighthouse und WebPageTest verschlechtert wird, was es derzeit besonders schwierig macht, die HTTP/3-Leistung mit HTTP/2 und HTTP/1.1 zu vergleichen. Fazit: HTTP/3 und QUIC sind wahrscheinlich noch nicht ganz bereit für die Primetime, aber sie werden es bald sein .
Empfehlungen
Aus der obigen Zusammenfassung scheint es, als würde ich starke Argumente gegen die Verwendung von QUIC oder HTTP/3 vorbringen. Das ist jedoch genau das Gegenteil von dem Punkt, den ich machen möchte.
Erstens, wie am Ende von Teil 2 besprochen, wird ein erheblicher Teil Ihrer Zielgruppe wahrscheinlich beeindruckende Verbesserungen feststellen , auch wenn Ihr „durchschnittlicher“ Benutzer möglicherweise keine großen Leistungssteigerungen feststellt (abhängig von Ihrem Zielmarkt) . 0-RTT spart vielleicht nur einen einzigen Roundtrip ein, aber das kann für einige Benutzer immer noch mehrere hundert Millisekunden bedeuten. Die Verbindungsmigration unterstützt möglicherweise keine konstant schnellen Downloads, aber sie wird definitiv denjenigen helfen, die versuchen, diese PDF in einem Hochgeschwindigkeitszug abzurufen. Paketverluste auf Kabeln können sprunghaft auftreten, aber drahtlose Verbindungen könnten mehr von der Head-of-Line-Blockierung von QUIC profitieren. Darüber hinaus sind diese Benutzer diejenigen, die normalerweise die schlechteste Leistung Ihres Produkts erfahren und folglich am stärksten davon betroffen sind. Wenn Sie sich fragen, warum das wichtig ist, lesen Sie Chris Zacharias' berühmte Web-Performance-Anekdote.
Zweitens werden QUIC und HTTP/3 mit der Zeit immer besser und schneller . Version 1 hat sich darauf konzentriert, das grundlegende Protokoll fertigzustellen, und erweiterte Leistungsmerkmale für später aufzubewahren. Daher denke ich, dass es sich auszahlt, jetzt in die Protokolle zu investieren, um sicherzustellen, dass Sie sie und die neuen Funktionen optimal nutzen können, wenn sie später verfügbar werden. Angesichts der Komplexität der Protokolle und ihrer Bereitstellungsaspekte wäre es gut, sich etwas Zeit zu nehmen, um sich mit ihren Macken vertraut zu machen. Auch wenn Sie sich noch nicht die Hände schmutzig machen möchten, bieten mehrere große CDN-Anbieter eine ausgereifte HTTP/3-Unterstützung zum Umlegen des Schalters an (insbesondere Cloudflare und Fastly). Ich habe Mühe, einen Grund zu finden, das nicht auszuprobieren, wenn Sie ein CDN verwenden (was Sie wirklich tun sollten, wenn Sie Wert auf Leistung legen).
Obwohl ich nicht sagen würde, dass es entscheidend ist, so schnell wie möglich mit der Verwendung von QUIC und HTTP/3 zu beginnen, habe ich das Gefühl, dass es bereits viele Vorteile gibt, die in Anspruch genommen werden können, und sie werden in Zukunft nur noch zunehmen .
Weiterführende Lektüre
Obwohl dies ein langer Textkörper war, kratzt er leider nur an der technischen Oberfläche der komplexen Protokolle, die QUIC und HTTP/3 sind.
Nachfolgend finden Sie eine Liste mit zusätzlichen Ressourcen zum Weiterlernen, mehr oder weniger in der Reihenfolge aufsteigender technischer Tiefe:
- „HTTP/3 erklärt“, Daniel Stenberg
Dieses E-Book des Entwicklers von cURL fasst das Protokoll zusammen. - „HTTP/2 in Aktion“, Barry Pollard
Dieses hervorragende Allround-Buch zu HTTP/2 enthält wiederverwendbare Ratschläge und einen Abschnitt zu HTTP/3. - @programmingart, Twitter
Meine Tweets widmen sich hauptsächlich QUIC, HTTP/3 und der Webleistung (einschließlich Nachrichten) im Allgemeinen. Siehe zum Beispiel meine letzten Threads zu QUIC-Features. - „YouTube“, Robin Marx
Meine über 10 ausführlichen Vorträge decken verschiedene Aspekte der Protokolle ab. - „Der Cloudlare-Blog“
Dabei handelt es sich um das Hauptprodukt eines Unternehmens, das nebenbei auch noch ein CDN betreibt. - „Der Fastly-Blog“
Dieser Blog enthält hervorragende Diskussionen zu technischen Aspekten, die in den breiteren Kontext eingebettet sind. - QUIC, die eigentlichen RFCs
Sie finden Links zu den IETF QUIC- und HTTP/3-RFC-Dokumenten und anderen offiziellen Erweiterungen. - IIJ Engineers Blog: Hervorragende technische Erläuterungen zu den Details der QUIC-Funktionen.
- Akademische Arbeiten zu HTTP/3 und QUIC, Robin Marx
Meine Forschungsarbeiten befassen sich mit Stream-Multiplexing und -Priorisierung, Tools und Implementierungsunterschieden. - QUIPS, EPIQ 2018 und EPIQ 2020
Diese Papiere aus akademischen Workshops enthalten eingehende Untersuchungen zu Sicherheit, Leistung und Erweiterungen der Protokolle.
Damit hinterlasse ich Ihnen, lieber Leser, ein hoffentlich stark verbessertes Verständnis dieser schönen neuen Welt. Ich bin immer offen für Feedback, also lassen Sie mich bitte wissen, was Sie von dieser Serie halten!
- Teil 1: Geschichte und Kernkonzepte von HTTP/3
Dieser Artikel richtet sich an Personen, die neu bei HTTP/3 und Protokollen im Allgemeinen sind, und behandelt hauptsächlich die Grundlagen. - Teil 2: HTTP/3-Leistungsmerkmale
Dieser ist mehr in die Tiefe und technisch. Leute, die bereits die Grundlagen kennen, können hier anfangen. - Teil 3: Praktische HTTP/3-Bereitstellungsoptionen
Dieser dritte Artikel der Reihe erläutert die Herausforderungen, die mit der Bereitstellung und dem Testen von HTTP/3 selbst verbunden sind. Es beschreibt auch, wie und ob Sie Ihre Webseiten und Ressourcen ändern sollten.