HTTP / 3: Grundsteinlegung und eine schöne neue Welt

Seit mehr als 20 Jahren betrachten wir Webseiten mit dem HTTP-Protokoll. Die meisten Benutzer denken überhaupt nicht darüber nach, was es ist und wie es funktioniert. Andere wissen, dass es irgendwo unter HTTP TLS gibt und darunter TCP, unter welcher IP und so weiter. Und die dritten - Ketzer - glauben, dass TCP das letzte Jahrhundert ist, sie wollen etwas schnelleres, zuverlässigeres und sichereres. Bei ihren Versuchen, ein neues ideales Protokoll zu erfinden, kehrten sie jedoch zu den Technologien der 80er Jahre zurück und versuchen, darauf ihre schöne neue Welt aufzubauen.


Ein bisschen Geschichte: HTTP / 1.1


1997 erhielt das Textaustauschprotokoll der HTTP-Version 1.1 seinen RFC. Zu dieser Zeit wurde das Protokoll mehrere Jahre lang von Browsern verwendet, und der neue Standard dauerte weitere fünfzehn Jahre. Das Protokoll arbeitete nur auf Anfrage-Antwort-Basis und war hauptsächlich für die Übertragung von Textinformationen gedacht.

HTTP wurde entwickelt, um auf dem TCP-Protokoll aufzubauen, das eine zuverlässige Zustellung von Paketen an das Ziel garantiert. TCP basiert auf dem Aufbau und der Aufrechterhaltung einer zuverlässigen Verbindung zwischen Endpunkten und der Segmentierung des Datenverkehrs. Segmente haben ihre eigene Sequenznummer und Prüfsumme. Wenn plötzlich eines der Segmente nicht kommt oder mit der falschen Prüfsumme kommt, stoppt die Übertragung, bis das verlorene Segment wiederhergestellt ist.

In HTTP / 1.0 wurde die TCP-Verbindung nach jeder Anforderung geschlossen. Es war seitdem extrem verschwenderisch Das Herstellen einer TCP-Verbindung (3-Wege-Handshake) ist kein schneller Vorgang. HTTP / 1.1 hat den Keep-Alive-Mechanismus eingeführt, mit dem Sie eine einzelne Verbindung für mehrere Anforderungen wiederverwenden können. Da dies jedoch leicht zu einem Engpass werden kann, sind in verschiedenen HTTP / 1.1-Implementierungen mehrere TCP / IP-Verbindungen zum selben Host zulässig. In Chrome und in neueren Versionen von Firefox sind beispielsweise bis zu sechs Verbindungen zulässig.

Die Verschlüsselung sollte auch anderen Protokollen überlassen werden. Zu diesem Zweck wurde das TLS-Protokoll über TCP verwendet, wodurch Daten zuverlässig geschützt wurden, die zum Herstellen einer Verbindung erforderliche Zeit jedoch weiter verlängert wurde. Infolgedessen sah der Handshake-Prozess folgendermaßen aus:

Cloudflare-Illustration

Daher hatte HTTP / 1.1 eine Reihe von Problemen:

  • Langsamer Verbindungsaufbau.
  • Eine TCP-Verbindung wird für eine Anforderung verwendet. Dies bedeutet, dass der Rest der Anforderungen entweder eine andere Verbindung finden oder warten muss, bis die aktuelle Anforderung sie freigibt.
  • Es wird nur das Pull-Modell unterstützt. Es gibt nichts im Standard über Server-Push.
  • Überschriften werden im Text übertragen.

Wenn Server-Push irgendwie mithilfe des WebSocket-Protokolls implementiert wird, mussten die restlichen Probleme radikaler behandelt werden.

Ein bisschen Modernität: HTTP / 2


Im Jahr 2012 begannen die Arbeiten am SPDY-Protokoll (ausgesprochen „Geschwindigkeit“) im Darm von Google. Das Protokoll wurde entwickelt, um die grundlegenden Probleme von HTTP / 1.1 zu lösen und gleichzeitig die Abwärtskompatibilität aufrechtzuerhalten. 2015 führte die IETF-Arbeitsgruppe die HTTP / 2-Spezifikation ein, die auf dem SPDY-Protokoll basiert. Hier sind die Unterschiede in HTTP / 2:

  • Binäre Serialisierung.
  • Multiplexen mehrerer HTTP-Anforderungen in eine einzige TCP-Verbindung.
  • Server-Push out of the Box (ohne WebSocket).

Das Protokoll war ein großer Schritt vorwärts. Es übertrifft die erste Version erheblich und erfordert nicht die Erstellung mehrerer TCP-Verbindungen: Alle Anforderungen an einen Host werden zu einem gemultiplext. Das heißt, in einer Verbindung gibt es mehrere sogenannte Streams, von denen jeder seine eigene ID hat. Der Bonus ist ein Boxed Server-Push.

Die Multiplikation führt jedoch zu einem weiteren Eckpfeilerproblem. Stellen Sie sich vor, wir führen asynchron 5 Anforderungen an einen Server aus. Bei Verwendung von HTTP / 2 werden alle diese Anforderungen innerhalb derselben TCP-Verbindung ausgeführt. Wenn also eines der Segmente einer Anforderung verloren geht oder falsch ankommt, wird die Übertragung aller Anforderungen und Antworten gestoppt, bis das verlorene Segment wiederhergestellt ist. Je schlechter die Verbindungsqualität ist, desto langsamer funktioniert HTTP / 2. Laut Daniel Stenberg ist HTTP / 1.1 in einem Browser in einer Situation, in der 2% aller verloren gegangenen Pakete ausmachen, besser als HTTP / 2, da 6 Verbindungen geöffnet werden und nicht eine.

Dieses Problem wird als "Head-of-Line-Blocking" bezeichnet und kann leider nicht mit TCP gelöst werden.

Illustration von Daniel Steinberg

Infolgedessen haben die Entwickler des HTTP / 2-Standards hervorragende Arbeit geleistet und fast alles getan, was auf Anwendungsebene des OSI-Modells möglich war. Es ist Zeit, auf die Transportebene zu gehen und ein neues Transportprotokoll zu erfinden.

Wir brauchen ein neues Protokoll: UDP vs TCP


Ziemlich schnell wurde klar, dass die Einführung eines völlig neuen Transportschichtprotokolls in der heutigen Realität eine unlösbare Aufgabe ist. Tatsache ist, dass die Drüsen oder Middleboxen (Router, Firewalls, NAT-Server ...) über die Transportebene Bescheid wissen und es etwas äußerst Schwieriges ist, ihnen etwas Neues beizubringen. Darüber hinaus ist die Unterstützung für Transportprotokolle mit dem Kernel von Betriebssystemen verbunden, und auch die Kernel ändern sich nicht so bereitwillig.

Und hier könnte man aufgeben und sagen: "Wir werden natürlich ein neues HTTP / 3 mit Präferenz und Kurtisanen erfinden, aber es wird in 10-15 Jahren implementiert (nach ungefähr dieser Zeit werden die meisten Drüsen ersetzt)", aber es gibt noch eines, nicht das meiste offensichtliche Option: Verwenden Sie das UDP-Protokoll. Ja, ja, dasselbe Protokoll, nach dem wir Ende der neunziger Jahre und Anfang Null Dateien in ein LAN geworfen haben. Fast alle heutigen Eisenstücke wissen, wie man damit arbeitet.

Was sind die Vorteile von UDP gegenüber TCP? Erstens haben wir keine Transport-Level-Sitzung, von der Iron weiß. Auf diese Weise können wir die Sitzung auf den Endpunkten selbst bestimmen und dort auftretende Konflikte lösen. Das heißt, wir sind nicht auf eine oder mehrere Sitzungen beschränkt (wie in TCP), sondern können sie so oft erstellen, wie wir benötigen. Zweitens ist die Datenübertragung über UDP schneller als über TCP. Theoretisch können wir also die heutige Geschwindigkeitsobergrenze von HTTP / 2 durchbrechen.

UDP garantiert jedoch keine zuverlässige Datenübertragung. Tatsächlich senden wir einfach Pakete in der Hoffnung, dass sie am anderen Ende empfangen werden. Nicht erhalten? Nun, kein Glück ... Dies war genug, um Videos für Erwachsene zu übertragen, aber für ernstere Dinge benötigen Sie Zuverlässigkeit, was bedeutet, dass Sie etwas anderes über UDP wickeln müssen.

Wie bei HTTP / 2 begannen die Arbeiten zur Erstellung eines neuen Protokolls 2012 bei Google, dh ungefähr zur gleichen Zeit wie der Beginn der Arbeiten an SPDY. 2013 stellte Jim Roskind der Öffentlichkeit das QUIC-Protokoll (Quick UDP Internet Connections) vor , und bereits 2015 wurde Internet Draft eingeführt, um die IETF zu standardisieren. Bereits zu diesem Zeitpunkt unterschied sich das von Roskind bei Google entwickelte Protokoll stark vom Standardprotokoll, sodass die Google-Version gQUIC hieß.

Was ist QUIC?


Erstens ist dies, wie bereits erwähnt, ein Wrapper über UDP. Die QUIC-Verbindung steigt über UDP an, in dem analog zu HTTP / 2 mehrere Streams existieren können. Diese Streams existieren nur an Endpunkten und werden unabhängig voneinander bereitgestellt. Wenn der Paketverlust in einem Stream aufgetreten ist, hat dies keine Auswirkungen auf die anderen.

Illustration von Daniel Steinberg

Zweitens wird die Verschlüsselung jetzt nicht mehr auf einer separaten Ebene implementiert, sondern im Protokoll enthalten. Auf diese Weise können Sie in einem einzigen Handshake eine Verbindung herstellen und öffentliche Schlüssel austauschen. Außerdem können Sie den kniffligen 0-RTT-Handshake-Mechanismus verwenden und im Allgemeinen Verzögerungen beim Händeschütteln vermeiden. Zusätzlich können jetzt einzelne Datenpakete verschlüsselt werden. Auf diese Weise können Sie nicht auf den Abschluss des Empfangs von Daten aus dem Stream warten, sondern die empfangenen Pakete unabhängig voneinander entschlüsseln. Diese Betriebsart war in TCP überhaupt nicht möglich, weil TLS und TCP arbeiteten unabhängig voneinander, und TLS konnte nicht wissen, in welche Teile TCP-Daten zerhacken würden. Daher konnte ich meine Segmente nicht so vorbereiten, dass sie eins zu eins in die TCP-Segmente passen und unabhängig voneinander entschlüsselt werden können. All diese Verbesserungen ermöglichen es QUIC, die Latenz im Vergleich zu TCP zu reduzieren.

Drittens können Sie mit dem Konzept der einfachen Streams die Verbindung von der IP-Adresse des Clients trennen. Dies ist beispielsweise wichtig, wenn ein Client von einem Wi-Fi-Zugangspunkt zu einem anderen wechselt und seine IP-Adresse ändert. In diesem Fall tritt bei Verwendung von TCP ein langwieriger Prozess auf, bei dem vorhandene TCP-Verbindungen im Zeitlimit abfallen und neue Verbindungen aus der neuen IP erstellt werden. Im Fall von QUIC sendet der Client einfach weiterhin Pakete von der neuen IP mit der alten Stream-ID an den Server. Weil Die Stream-ID ist jetzt eindeutig und wird nicht wiederverwendet. Der Server versteht, dass der Client die IP geändert hat, sendet die verlorenen Pakete und setzt die Kommunikation an die neue Adresse fort.

Viertens wird QUIC auf Anwendungsebene implementiert, nicht auf dem Betriebssystem. Dies ermöglicht zum einen schnellere Änderungen des Protokolls als Um ein Update zu erhalten, aktualisieren Sie einfach die Bibliothek, anstatt auf eine neue Version des Betriebssystems zu warten. Dies führt andererseits zu einem starken Anstieg des Prozessorverbrauchs.

Und schließlich die Schlagzeilen. Die Header-Komprimierung bezieht sich nur auf Punkte, die sich in QUIC und gQUIC unterscheiden. Ich sehe keinen Grund, viel Zeit dafür aufzuwenden. Ich kann nur sagen, dass in der zur Standardisierung eingereichten Version die Header-Komprimierung der Header-Komprimierung in HTTP / 2 so ähnlich wie möglich gemacht wurde. Weitere Details finden Sie hier .

Wie viel schneller ist es?


Dies ist eine schwierige Frage. Tatsache ist, dass wir zwar keinen Standard haben, aber nichts Besonderes zu messen ist. Möglicherweise sind die einzigen Statistiken, die wir haben, die Statistiken von Google, die seit 2013 gQUIC verwenden und 2016 der IETF gemeldet haben, dass etwa 90% des Datenverkehrs, der vom Chrome-Browser zu ihren Servern geleitet wird, jetzt QUIC verwendet. In derselben Präsentation berichten sie, dass Seiten durch gQUIC etwa 5% schneller geladen werden und Streaming-Videos 30% weniger Einfrierungen aufweisen als TCP.

Im Jahr 2017 veröffentlichte eine Gruppe von Forschern unter der Leitung von Arash Molavi Kakhki eine umfangreiche Arbeit zur Untersuchung der gQUIC-Leistung im Vergleich zu TCP.
Die Studie ergab mehrere gQUIC-Schwachstellen, wie z. B. Instabilität beim Mischen von Netzwerkpaketen, ungerechte Kanalkapazität und langsamere Übertragung kleiner (bis zu 10 kb) Objekte. Letzteres kann jedoch mit der 0-RTT kompensiert werden. In allen anderen untersuchten Fällen zeigte gQUIC eine Geschwindigkeitssteigerung im Vergleich zu TCP. Es ist schwer, über bestimmte Zahlen zu sprechen. Es ist besser, die Studie selbst oder einen kurzen Beitrag zu lesen.

Hier muss gesagt werden, dass es sich bei diesen Daten speziell um gQUIC handelt und sie für den zu entwickelnden Standard irrelevant sind. Was für QUIC passieren wird: Bisher steckt das Geheimnis hinter sieben Siegeln, aber es besteht die Hoffnung, dass die von gQUIC identifizierten Schwächen berücksichtigt und korrigiert werden.

Eine kleine Zukunft: Was ist mit HTTP / 3?


Und hier ist alles glasklar: Die API wird sich in keiner Weise ändern. Alles bleibt genau so wie in HTTP / 2. Wenn die API unverändert bleibt, muss der Übergang zu HTTP / 3 mithilfe der neuesten Version der Bibliothek entschieden werden, die den Transport über QUIC im Backend unterstützt. Es stimmt, Sie müssen noch lange auf ältere Versionen von HTTP zurückgreifen, weil Das Internet ist jetzt nicht bereit für einen vollständigen Wechsel zu UDP.

Wer unterstützt schon


Hier ist eine Liste der vorhandenen QUIC-Implementierungen. Trotz des Fehlens eines Standards ist die Liste nicht schlecht.

Derzeit unterstützt kein Browser QUIC in der Version. Kürzlich gab es Informationen, dass Chrome HTTP / 3-Unterstützung enthielt, bisher jedoch nur auf Kanarienvogel.

Von den Backends unterstützt HTTP / 3 nur Caddy und Cloudflare , bisher jedoch experimentell. NGINX gab im späten Frühjahr 2019 bekannt, dass sie mit der Arbeit an der HTTP / 3-Unterstützung begonnen, diese jedoch noch nicht abgeschlossen haben.

Was sind die Probleme


Wir leben in der realen Welt, in der keine einzige große Technologie in die Massen gelangen kann, ohne auf Widerstand zu stoßen, und QUIC ist keine Ausnahme.

Am wichtigsten ist, dass Sie dem Browser irgendwie erklären müssen, dass „https: //“ keine Tatsache mehr ist, die zum 443. TCP-Port führt. Möglicherweise ist überhaupt kein TCP vorhanden. Verwenden Sie dazu den Alt-Svc-Header. Dadurch kann der Browser darüber informiert werden, dass diese Website auch unter diesem und jenem Protokoll unter dieser oder jener Adresse verfügbar ist. Theoretisch sollte dies wie eine Uhr funktionieren, in der Praxis stoßen wir jedoch auf die Tatsache, dass UDP beispielsweise in der Firewall deaktiviert werden kann, um DDoS-Angriffe zu vermeiden.

Aber selbst wenn UDP nicht verboten ist, befindet sich der Client möglicherweise hinter einem NAT-Router, der so konfiguriert ist, dass er eine TCP-Sitzung nach IP-Adresse als hält Wir verwenden UDP, in dem keine Hardwaresitzung vorhanden ist, NAT die Verbindung nicht hält und die QUIC-Sitzung immer beendet wird .

All diese Probleme hängen mit der Tatsache zusammen, dass UDP zuvor nicht zur Übertragung von Internetinhalten verwendet wurde und die Hardwarehersteller nicht vorhersehen konnten, dass dies jemals passieren würde. Auf die gleiche Weise verstehen Administratoren noch nicht, wie sie ihre Netzwerke für QUIC richtig konfigurieren können. Diese Situation wird sich langsam ändern, und in jedem Fall werden solche Änderungen weniger Zeit in Anspruch nehmen als die Einführung eines neuen Transportschichtprotokolls.

Darüber hinaus erhöht QUIC, wie bereits beschrieben, die Prozessorauslastung erheblich. Daniel Stenberg bewertete das Wachstum des Prozessors bis zu dreimal.

Wenn HTTP / 3 kommt


Sie wollen den Standard bis Mai 2020 übernehmen, aber da die für Juli 2019 geplanten Dokumente noch nicht fertig sind, können wir sagen, dass der Termin höchstwahrscheinlich verschoben wird.

Nun, Google verwendet seit 2013 die Implementierung von gQUIC. Wenn Sie sich die HTTP-Anfrage ansehen, die an die Google-Suchmaschine gesendet wird, sehen Sie Folgendes:


Schlussfolgerungen


QUIC sieht jetzt wie eine ziemlich grobe, aber sehr vielversprechende Technologie aus. In Anbetracht dessen, dass in den letzten 20 Jahren alle Optimierungen der Transportschichtprotokolle, die sich hauptsächlich auf TCP, QUIC beziehen und in den meisten Fällen an Leistung gewinnen, jetzt äußerst gut aussehen.

Es gibt jedoch noch ungelöste Probleme, die in den nächsten Jahren gelöst werden müssen. Der Prozess kann sich aufgrund der Tatsache verzögern, dass Hardware beteiligt ist, die niemand gerne aktualisiert, aber dennoch sehen alle Probleme ziemlich lösbar aus, und früher oder später werden wir alle HTTP / 3 haben.

Die Zukunft ist nicht mehr fern!

Source: https://habr.com/ru/post/de473930/


All Articles