Seit über 20 Jahren betrachten wir Webseiten über das HTTP-Protokoll. Die meisten Nutzer denken überhaupt nicht darüber nach, was es ist und wie es funktioniert. Andere wissen, dass hinter HTTP TLS steckt, darunter TCP, darunter IP und so weiter. Und einige – die Eretiker – glauben, dass TCP altmodisch ist und möchten etwas Schnelleres, Zuverlässigeres und Sichereres. Doch in ihren Bemühungen, ein neues, ideales Protokoll zu erfinden, sind sie zu den Technologien der 80er Jahre zurückgekehrt und versuchen, ihre wundersame neue Welt darauf aufzubauen.

Ein wenig Geschichte: HTTP/1.1
Im Jahr 1997 erhielt das Textinformationsübertragungsprotokoll HTTP Version 1.1 sein RFC. Zu diesem Zeitpunkt wurde das Protokoll bereits seit mehreren Jahren von Browsern verwendet, und der neue Standard hielt weitere fünfzehn Jahre. Das Protokoll arbeitete ausschließlich nach dem Prinzip Anfrage-Antwort und war hauptsächlich für die Übertragung von Textinformationen gedacht.
HTTP wurde entworfen, um über das TCP-Protokoll zu arbeiten, das eine zuverlässige Lieferung von Paketen an den Empfänger garantiert. Die Funktionsweise von TCP basiert auf der Einrichtung und Wartung einer zuverlässigen Verbindung zwischen den Endpunkten und der Segmentierung des Datenverkehrs. Segmente haben ihre eigene Sequenznummer und Prüfziffer. Wenn eines der Segmente nicht ankommt oder mit einer falschen Prüfziffer ankommt, wird die Übertragung unterbrochen, bis das verlorene Segment wiederhergestellt ist.
In HTTP/1.0 wurde die TCP-Verbindung nach jeder Anfrage geschlossen. Das war äußerst verschwenderisch, da die Einrichtung einer TCP-Verbindung (3-Way-Handshake) kein schneller Prozess ist. In HTTP/1.1 wurde der keep-alive-Mechanismus eingeführt, der es ermöglicht, eine Verbindung für mehrere Anfragen wiederzuverwenden. Allerdings kann diese leicht zum Engpass werden, weshalb verschiedene Implementierungen von HTTP/1.1 die Eröffnung mehrerer TCP-Verbindungen zu einem Host zulassen. Zum Beispiel erlaubt Chrome und die neuesten Versionen von Firefox bis zu sechs Verbindungen.

Die Verschlüsselung sollte ebenfalls anderen Protokollen überlassen werden, und daher wurde über TCP das TLS-Protokoll verwendet, das die Daten ausreichend sicher schützte, aber die Zeit für die Herstellung der Verbindung zusätzlich erhöhte. Letztendlich sah der Handshake-Prozess wie folgt aus:

Illustration von Cloudflare
So hatte HTTP/1.1 eine Reihe von Problemen:
- Langsame Verbindungsherstellung.
- Daten werden im Klartext übermittelt, was die Übertragung von Bildern, Videos und anderen nicht-textuellen Informationen ineffizient macht.
- Eine TCP-Verbindung wird für eine Anfrage verwendet, was bedeutet, dass andere Anfragen entweder eine andere Verbindung finden oder warten müssen, bis die aktuelle Anfrage sie freigibt.
- Es wird nur das Pull-Modell unterstützt. Der Standard sieht nichts für Server-Push vor.
- Die Header werden im Textformat übertragen.
Wenn Server-Push mehr oder weniger mit dem WebSocket-Protokoll umgesetzt wird, müssen die anderen Probleme radikaler gelöst werden.
Ein wenig Moderne: HTTP/2
Im Jahr 2012 begann Google mit der Arbeit an dem Protokoll SPDY (ausgesprochen „speedy“). Das Protokoll sollte die Hauptprobleme von HTTP/1.1 lösen und gleichzeitig abwärtskompatibel bleiben. Im Jahr 2015 stellte die IETF-Arbeitsgruppe die Spezifikation HTTP/2 vor, die auf dem SPDY-Protokoll basiert. Hier sind die Unterschiede in HTTP/2:
- Binäre Serialisierung.
- Multiplexing mehrerer HTTP-Anfragen in einer einzigen TCP-Verbindung.
- Server-Push out of the box (ohne WebSocket).
Das Protokoll stellt einen großen Schritt nach vorne dar. Es übertrifft die erste Version erheblich in der Geschwindigkeit Allerdings führt Multiplexing zu einem anderen grundlegenden Problem. Stellen Sie sich vor, wir führen asynchron 5 Anfragen an denselben Server aus. Bei der Verwendung von HTTP/2 werden alle diese Anfragen innerhalb einer TCP-Verbindung verarbeitet, was bedeutet, dass wenn ein Segment einer Anfrage verloren geht oder falsch ankommt, die Übertragung aller Anfragen und Antworten gestoppt wird, bis das verlorene Segment wiederhergestellt ist. Offensichtlich arbeitet HTTP/2 umso langsamer, je schlechter die Verbindungsqualität ist.
Laut Daniel Stenberg Dieses Problem wird als „head-of-line blocking“ bezeichnet, und leider scheint es mit der Verwendung von TCP nicht lösbar.
Illustration von Daniel Steinberg

Illustration Daniel Steinberg
Insgesamt haben die Entwickler des Standards HTTP/2 großartige Arbeit geleistet und praktisch alles umgesetzt, was auf der Anwendungsebene des OSI-Modells möglich war. Es ist an der Zeit, auf die Transportschicht hinunterzusteigen und ein neues Transportprotokoll zu erfinden.
Wir brauchen ein neues Protokoll: UDP vs TCP
Es wurde schnell klar, dass die Einführung eines völlig neuen Transportprotokolls in der heutigen Realität eine unlösbare Aufgabe ist. Der Grund dafür ist, dass die Hardware oder Middle-Boxes (Router, Firewalls, NAT-Server...) über die Transportschicht Bescheid wissen, und es ist äußerst schwierig, sie etwas Neues zu lehren. Außerdem ist die Unterstützung von Transportprotokollen im Kern der Betriebssysteme verankert, und die Kerne ändern sich auch nicht so schnell.
Man könnte an dieser Stelle aufgeben und sagen: „Natürlich erfinden wir ein neues HTTP/3 mit Spaß und Kurven, aber die Einführung wird 10-15 Jahre dauern (ungefähr in dieser Zeit werden die meisten Geräte ersetzt werden)“, aber es gibt noch eine andere, nicht ganz offensichtliche Möglichkeit: das UDP-Protokoll zu verwenden. Ja, genau das Protokoll, mit dem wir in den späten 90ern und frühen 2000er Jahren lokale Dateien hin- und hergeschickt haben. Praktisch alle heutigen Geräte können damit umgehen.
Was sind die Vorteile von UDP im Vergleich zu TCP? Zunächst einmal haben wir keine Transportschicht-Sitzung, die die Hardware kennt. Das erlaubt uns, die Sitzung an den Endpunkten selbst zu definieren und dort auftretende Konflikte zu lösen. Das heißt, wir sind nicht auf eine oder mehrere Sitzungen (wie bei TCP) beschränkt, sondern können so viele erstellen, wie wir brauchen. Zweitens geschieht die Datenübertragung über UDP schneller als über TCP. Theoretisch können wir somit die heutige Geschwindigkeitsgrenze, die in HTTP/2 erreicht wurde, durchbrechen.
Allerdings garantiert UDP keine zuverlässige Datenübertragung. Tatsächlich senden wir einfach Pakete und hoffen, dass sie am anderen Ende empfangen werden. Wurden sie nicht empfangen? Pech gehabt... Das hat für die Übertragung von Erwachsenen-Videos ausgereicht, aber für ernstere Dinge ist Zuverlässigkeit erforderlich, also müssen wir etwas über UDP legen.
Wie auch bei HTTP/2 begann die Arbeit an einem neuen Protokoll bei Google im Jahr 2012, also ungefähr zur gleichen Zeit, als die Entwicklung von SPDY begann. Im Jahr 2013 stellte Jim Roskind der Öffentlichkeit , und bereits 2015 wurde ein Internet Draft zur Standardisierung bei der IETF eingereicht. Zu diesem Zeitpunkt unterschied sich das von Roskind bei Google entwickelte Protokoll stark von dem zur Standardisierung vorgestellten, weshalb die Google-Version als gQUIC bezeichnet wurde.
Was ist QUIC?
Erstens, wie bereits erwähnt, ist es eine Hülle über UDP. Über UDP wird eine QUIC-Verbindung aufgebaut, in der ähnlich wie bei HTTP/2 mehrere Streams existieren können. Diese Streams existieren nur an den Endpunkten und werden unabhängig verwaltet. Wenn ein Paket in einem Stream verloren geht, betrifft dies die anderen nicht.

Illustration Daniel Steinberg
Zweitens wird die Verschlüsselung jetzt nicht mehr auf einer separaten Ebene, sondern integriert in das Protokoll realisiert. Das ermöglicht den Aufbau einer Verbindung und den Austausch öffentlicher Schlüssel in einem einzigen Handshake sowie die Verwendung des cleveren 0-RTT-Handshakes, um Verzögerungen bei dem Handshake zu vermeiden. Darüber hinaus können nun einzelne Datenpakete verschlüsselt werden. Das erlaubt es, die Empfangsbestätigung von Daten aus dem Stream zu vermeiden und empfangene Pakete unabhängig zu entschlüsseln. Dieser Arbeitsmodus war bei TCP überhaupt nicht möglich, da TLS und TCP unabhängig voneinander arbeiteten, und TLS nicht wusste, in welche Teile die Daten von TCP zerlegt werden. Daher konnte es seine Segmente nicht so vorbereiten, dass sie 1:1 in die TCP-Segmente passten und unabhängig entschlüsselt werden konnten. All diese Verbesserungen ermöglichen es QUIC, die Latenz im Vergleich zu TCP zu verringern.

Drittens ermöglicht das Konzept der leichten Streams, die Verbindung von der IP-Adresse des Clients zu lösen. Dies ist wichtig, zum Beispiel, wenn der Client von einem Wi-Fi-Zugangspunkt zu einem anderen wechselt und seine IP-Adresse ändert. In diesem Fall findet bei der Verwendung von TCP ein langwieriger Prozess statt, bei dem bestehende TCP-Verbindungen aufgrund von Zeitüberschreitungen abbrechen und neue Verbindungen mit der neuen IP hergestellt werden. Bei QUIC sendet der Client einfach weiterhin Pakete an den Server von der neuen IP mit der alten Stream-ID. Da die Stream-ID nun einzigartig und nicht wiederverwendet wird, erkennt der Server, dass der Client die IP gewechselt hat, sendet verlorene Pakete nach und setzt die Kommunikation unter der neuen Adresse fort.
Viertens, QUIC wird auf Anwendungsebene und nicht auf Betriebssystemebene implementiert. Dadurch können Änderungen am Protokoll schneller vorgenommen werden, da man lediglich die Bibliothek aktualisieren muss, anstatt auf eine neue Version des Betriebssystems zu warten. Andererseits führt das zu einem signifikanten Anstieg der CPU-Auslastung.
Und zum Schluss die Header. Die Komprimierung der Header gehört zu den Aspekten, die QUIC und gQUIC unterscheiden. Ich sehe keinen Sinn darin, viel Zeit darauf zu verwenden, ich kann nur sagen, dass in der zur Standardisierung eingereichten Version die Komprimierung der Header möglichst ähnlich der Komprimierung in HTTP/2 gestaltet wurde. Mehr Details sind verfügbar. .
Wie viel schneller ist es?
Das ist eine komplexe Frage. Das Problem ist, dass wir noch keinen Standard haben und es daher nicht viel zu messen gibt. Die einzigen statistischen Daten, über die wir verfügen, sind die von Google, das seit 2013 gQUIC nutzt und 2016 , dass etwa 90 % des Traffics von ihrem Chrome-Browser jetzt QUIC verwendet. In derselben Präsentation geben sie an, dass gQUIC Seiten etwa 5 % schneller lädt und dass es bei Streaming-Videos 30 % weniger Ruckler im Vergleich zu TCP gibt.
Im Jahr 2017 veröffentlichte eine Forschergruppe unter der Leitung von Arash Molavi Kakhki eine Studie über die Leistung von gQUIC im Vergleich zu TCP.
Die Untersuchung zeigte mehrere Schwächen von gQUIC, wie die Instabilität gegenüber der Vermischung von Netzwerkpaketen, die Ungerechtigkeit bei der Bandbreitennutzung und die langsamere Übertragung kleiner (bis zu 10 kB) Objekte. Letzteres kann jedoch durch die Verwendung von 0-RTT ausgeglichen werden. In allen anderen untersuchten Fällen zeigte gQUIC eine Geschwindigkeitsteigerung gegenüber TCP. Über konkrete Zahlen ist hier jedoch nichts zu sagen. Am besten ist es, oder .
Hier sollte erwähnt werden, dass diese Daten spezifisch für gQUIC sind und für den entwickelten Standard nicht mehr zutreffen. Was für QUIC gelten wird, bleibt noch ein Geheimnis, aber es besteht Hoffnung, dass die identifizierten Schwächen von gQUIC berücksichtigt und behoben werden.
Ein Blick in die Zukunft: Was ist mit HTTP/3?
Hier ist alles klar: Die API wird sich nicht ändern. Es bleibt alles so, wie es auch bei HTTP/2 war. Wenn die API gleich bleibt, muss der Übergang zu HTTP/3 über die Verwendung einer aktualisierten Backend-Bibliothek, die den Transport über QUIC unterstützt, geregelt werden. Allerdings wird es noch eine Weile dauern, bis man das Fallback auf ältere HTTP-Versionen aufgeben kann, da das Internet derzeit noch nicht bereit für einen vollständigen Übergang zu UDP ist.
Wer unterstützt bereits
Hier bestehende Implementierungen von QUIC. Trotz der fehlenden Standardisierung ist die Liste nicht schlecht.
Kein Browser unterstützt derzeit QUIC in der stabilen Version. Kürzlich gab es Informationen, dass Chrome Unterstützung für HTTP/3 aktiviert hat, aber bisher nur in der Canary-Version.
Von den Backends unterstützt nur und , allerdings noch experimentell. NGINX hatte Ende des Frühlings 2019 , dass sie an der Unterstützung für HTTP/3 arbeiten, aber noch nicht abgeschlossen haben.
Welche Probleme gibt es?
Wir leben in einer realen Welt, in der keine große Technologie ohne Widerstand in die Massen gelangt, und QUIC ist da keine Ausnahme.
Das Wichtigste ist, dem Browser irgendwie zu erklären, dass “https://” nicht unbedingt zum 443. TCP-Port führt. Dort könnte es möglicherweise kein TCP geben. Dafür wird der Alt-Svc-Header verwendet. Dieser ermöglicht es, dem Browser mitzuteilen, dass diese Webseite auch über ein bestimmtes Protokoll unter einer bestimmten Adresse erreichbar ist. In der Theorie sollte das reibungslos funktionieren, aber in der Praxis stoßen wir darauf, dass UDP beispielsweise in Firewalls blockiert sein kann, um DDoS-Angriffe zu vermeiden.
Selbst wenn UDP nicht blockiert ist, kann sich der Client hinter einem NAT-Router befinden, der darauf eingestellt ist, die TCP-Sitzung über die IP-Adresse aufrechtzuerhalten. Da wir jedoch UDP verwenden, in dem es keine physische Sitzung gibt, wird NAT die Verbindung nicht aufrechterhalten, wodurch die QUIC-Sitzung .
All diese Probleme hängen damit zusammen, dass UDP zuvor nicht zur Übertragung von Internetinhalten verwendet wurde und Hardwarehersteller nicht vorhersehen konnten, dass dies eines Tages geschehen würde. Diese Situation wird sich allmählich ändern, und in jedem Fall werden solche Änderungen weniger Zeit in Anspruch nehmen als die Einführung eines neuen Transportprotokolls.
Darüber hinaus, wie bereits beschrieben, führt QUIC zu einem erheblichen Anstieg der CPU-Nutzung. Daniel Stenberg ein Wachstum der CPU-Nutzung um das Dreifache.
Wann wird HTTP/3
Standard werden? Ziel ist es, bis Mai 2020 zu erreichen, aber angesichts der Tatsache, dass zum gegenwärtigen Zeitpunkt die Dokumente, die für Juli 2019 geplant waren, noch unvollständig sind, kann man sagen, dass das Datum wahrscheinlich verschoben wird.
Google verwendet seit 2013 seine eigene Implementierung von gQUIC. Wenn man sich die HTTP-Anfrage ansieht, die an die Google-Suchmaschine gesendet wird, kann man Folgendes erkennen:

Fazit
QUIC erscheint derzeit zwar als eine etwas unausgereifte, aber sehr vielversprechende Technologie. Angesichts dessen, dass die letzten 20 Jahre alle Optimierungen der Transportschichtprotokolle hauptsächlich auf TCP abzielten, sieht QUIC, das in den meisten Fällen hinsichtlich der Leistung überlegen ist, bereits jetzt ziemlich gut aus.
Es gibt jedoch noch ungelöste Probleme, die in den kommenden Jahren angegangen werden müssen. Der Prozess könnte sich hinziehen, da Hardware beteiligt ist, die niemand gerne aktualisiert, doch alle Probleme erscheinen durchaus lösbar, und früher oder später werden wir alle HTTP/3 haben.
Die Zukunft steht vor der Tür!
Quelle: habr.com
