HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat

Od ponad 20 lat przeglądamy strony internetowe korzystając z protokołu HTTP. Większość użytkowników nawet nie myśli o tym, co to jest i jak działa. Inni wiedzą, że gdzieś pod HTTP znajduje się TLS, a pod nim TCP, pod którym znajduje się IP i tak dalej. A jeszcze inni – heretycy – uważają, że TCP to już przeszłość; chcą czegoś szybszego, bardziej niezawodnego i bezpiecznego. Jednak próbując wynaleźć nowy idealny protokół, powrócili do technologii z lat 80. i próbują na niej zbudować swój nowy, wspaniały świat.
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat

Trochę historii: HTTP/1.1

W 1997 r. protokół wymiany informacji tekstowych HTTP w wersji 1.1 uzyskał własny dokument RFC. W tamtym czasie protokół był używany przez przeglądarki już od kilku lat, a nowy standard przetrwał kolejne piętnaście lat. Protokół działał wyłącznie na zasadzie żądanie-odpowiedź i przeznaczony był głównie do przesyłania informacji tekstowych.

HTTP został zaprojektowany tak, aby działał na bazie protokołu TCP, zapewniając niezawodne dostarczanie pakietów do miejsca przeznaczenia. TCP działa poprzez ustanawianie i utrzymywanie niezawodnego połączenia pomiędzy punktami końcowymi oraz dzielenie ruchu na segmenty. Segmenty mają swój własny numer seryjny i sumę kontrolną. Jeżeli nagle jeden z segmentów nie dotrze lub dotrze z nieprawidłową sumą kontrolną, transmisja zostanie zatrzymana do czasu przywrócenia utraconego segmentu.

W HTTP/1.0 połączenie TCP było zamykane po każdym żądaniu. Było to niezwykle marnotrawstwo, ponieważ... ustanawianie połączenia TCP (3-Way-Handshake) jest procesem powolnym. W HTTP/1.1 wprowadzono mechanizm keep-alive, który umożliwia ponowne wykorzystanie jednego połączenia do wielu żądań. Ponieważ jednak może łatwo stać się wąskim gardłem, różne implementacje protokołu HTTP/1.1 umożliwiają otwieranie wielu połączeń TCP z tym samym hostem. Na przykład przeglądarka Chrome i najnowsze wersje przeglądarki Firefox umożliwiają maksymalnie sześć połączeń.
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat
Szyfrowanie również miało zostać pozostawione innym protokołom i do tego wykorzystano protokół TLS poprzez TCP, który niezawodnie chronił dane, ale dodatkowo wydłużał czas potrzebny na nawiązanie połączenia. W rezultacie proces uzgadniania zaczął wyglądać następująco:
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat
Ilustracja Cloudflare'a

Zatem HTTP/1.1 miał wiele problemów:

  • Powolna konfiguracja połączenia.
  • Dane przesyłane są w formie tekstowej, co oznacza, że ​​przesyłanie zdjęć, filmów i innych informacji nietekstowych jest nieskuteczne.
  • Jedno połączenie TCP jest używane dla jednego żądania, co oznacza, że ​​inne żądania muszą albo znaleźć inne połączenie, albo poczekać, aż bieżące żądanie je zwolni.
  • Obsługiwany jest tylko model ciągnący. W standardzie nie ma nic na temat wypychania serwerów.
  • Nagłówki przesyłane są w formie tekstu.

Jeśli serwer push zostanie przynajmniej zaimplementowany przy użyciu protokołu WebSocket, wówczas pozostałe problemy będą musiały zostać rozwiązane bardziej radykalnie.

Trochę nowoczesności: HTTP/2

W 2012 roku Google rozpoczął prace nad protokołem SPDY (wymawiane „szybki”). Protokół miał rozwiązać główne problemy protokołu HTTP/1.1 i jednocześnie miał zachować kompatybilność wsteczną. W 2015 roku grupa robocza IETF wprowadziła specyfikację HTTP/2 opartą na protokole SPDY. Oto różnice w HTTP/2:

  • Serializacja binarna.
  • Multipleksowanie wielu żądań HTTP w jedno połączenie TCP.
  • Serwer typu push po wyjęciu z pudełka (bez protokołu WebSocket).

Protokół był dużym krokiem naprzód. On mocno szybkością bije pierwszą wersję i nie wymaga tworzenia wielu połączeń TCP: wszystkie żądania kierowane do jednego hosta są multipleksowane w jedno. Oznacza to, że w jednym połączeniu znajduje się kilka tzw. strumieni, z których każdy ma swój własny identyfikator. Bonusem jest pudełkowaty serwer push.

Jednakże multipleksowanie prowadzi do innego kluczowego problemu. Wyobraź sobie, że asynchronicznie wykonujemy 5 żądań do jednego serwera. W przypadku korzystania z protokołu HTTP/2 wszystkie te żądania będą realizowane w ramach tego samego połączenia TCP, co oznacza, że ​​jeśli jeden z segmentów dowolnego żądania zostanie utracony lub odebrany niepoprawnie, transmisja wszystkich żądań i odpowiedzi zostanie zatrzymana do czasu, gdy utracony segment zostanie przywrócony. Oczywiście im gorsza jakość połączenia, tym wolniej działa HTTP/2. Według Daniela Stenberga, w warunkach gdzie utracone pakiety stanowią 2% wszystkich pakietów, HTTP/1.1 w przeglądarce działa lepiej niż HTTP/2 ze względu na to, że otwiera 6 połączeń a nie jedno.

Problem ten nazywany jest „blokowaniem nagłówka linii” i niestety nie można go rozwiązać przy użyciu protokołu TCP.
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat
Ilustracja autorstwa Daniela Steinberga

W efekcie twórcy standardu HTTP/2 wykonali świetną robotę i zrobili niemal wszystko, co można było zrobić w warstwie aplikacyjnej modelu OSI. Czas zejść na warstwę transportową i wymyślić nowy protokół transportowy.

Potrzebujemy nowego protokołu: UDP vs TCP

Dość szybko stało się jasne, że wdrożenie zupełnie nowego protokołu warstwy transportowej jest zadaniem niemożliwym w dzisiejszych realiach. Faktem jest, że sprzęt lub urządzenia pośrednie (routery, zapory ogniowe, serwery NAT...) znają warstwę transportową i nauczenie ich czegoś nowego jest niezwykle trudnym zadaniem. Ponadto obsługa protokołów transportowych jest wbudowana w jądro systemów operacyjnych, a jądra również nie są zbyt skłonne do zmian.

I tutaj można by załamać ręce i powiedzieć: „Oczywiście wymyślimy nowy HTTP/3 z preferencjami i kurtyzanami, ale jego wdrożenie zajmie 10-15 lat (po mniej więcej tym czasie większość sprzętu będzie zastąpiony)”, ale jest jeszcze jeden, więc oczywistą opcją jest użycie protokołu UDP. Tak, tak, ten sam protokół, którego używaliśmy do przesyłania plików przez sieć LAN pod koniec lat dziewięćdziesiątych i na początku XXI wieku. Prawie cały dzisiejszy sprzęt może z nim współpracować.

Jakie są zalety UDP nad TCP? Po pierwsze, nie mamy sesji warstwy transportowej, o której sprzęt wie. Dzięki temu możemy sami określić sesję na punktach końcowych i rozwiązać tam konflikty. Oznacza to, że nie jesteśmy ograniczeni do jednej czy kilku sesji (jak w TCP), ale możemy stworzyć ich tyle, ile potrzebujemy. Po drugie, transmisja danych poprzez UDP jest szybsza niż poprzez TCP. Zatem teoretycznie możemy przełamać obecny pułap prędkości osiągany w HTTP/2.

Jednakże UDP nie gwarantuje niezawodnej transmisji danych. W rzeczywistości po prostu wysyłamy pakiety, mając nadzieję, że drugi koniec je otrzyma. Nie otrzymałem? No cóż, nie udało się... To wystarczyło do przesyłania filmów dla dorosłych, ale do poważniejszych rzeczy potrzebna jest niezawodność, co oznacza, że ​​trzeba owinąć coś innego na UDP.

Podobnie jak w przypadku HTTP/2, prace nad stworzeniem nowego protokołu rozpoczęły się w Google w 2012 roku, czyli mniej więcej w tym samym czasie, gdy rozpoczęły się prace nad SPDY. W 2013 roku Jim Roskind przedstawił publiczności Protokół QUIC (Szybkie połączenia internetowe UDP)., a już w 2015 roku wprowadzono do standaryzacji w IETF Internet Draft. Już wtedy protokół opracowany przez Roskinda w Google bardzo odbiegał od standardu, dlatego wersja Google zaczęto nazywać gQUIC.

Co to jest QUIK

Po pierwsze, jak już wspomniano, jest to opakowanie na protokół UDP. Połączenie QUIC powstaje nad UDP, w którym analogicznie do HTTP/2 może istnieć kilka strumieni. Strumienie te istnieją tylko w punktach końcowych i są obsługiwane niezależnie. Jeśli utrata pakietu nastąpi w jednym strumieniu, nie będzie to miało wpływu na inne.
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat
Ilustracja autorstwa Daniela Steinberga

Po drugie, szyfrowanie nie jest już realizowane na osobnym poziomie, ale jest uwzględnione w protokole. Pozwala to na nawiązanie połączenia i wymianę kluczy publicznych w ramach jednego uścisku dłoni, a także pozwala na wykorzystanie sprytnego mechanizmu uzgadniania 0-RTT i całkowite uniknięcie opóźnień podczas uzgadniania. Ponadto możliwe jest teraz szyfrowanie poszczególnych pakietów danych. Pozwala to nie czekać na zakończenie odbioru danych ze strumienia, ale samodzielnie odszyfrować odebrane pakiety. Ten tryb działania był generalnie niemożliwy w protokole TCP, ponieważ TLS i TCP działały niezależnie od siebie i TLS nie wiedział, na jakie części dane TCP zostaną pocięte. Dlatego nie mógł przygotować swoich segmentów tak, aby pasowały do ​​​​segmentów TCP jeden do jednego i mogły być niezależnie odszyfrowane. Wszystkie te ulepszenia pozwalają QUIC zmniejszyć opóźnienia w porównaniu do protokołu TCP.
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat
Po trzecie, koncepcja strumieniowania światła pozwala na oddzielenie połączenia od adresu IP klienta. Jest to istotne np. wtedy, gdy klient przełącza się z jednego punktu dostępowego Wi-Fi na inny, zmieniając swój adres IP. W takim przypadku podczas korzystania z protokołu TCP następuje długi proces, podczas którego przekroczono limit czasu istniejących połączeń TCP i tworzone są nowe połączenia z nowego adresu IP. W przypadku QUIC klient po prostu kontynuuje wysyłanie pakietów do serwera z nowego adresu IP ze starym identyfikatorem strumienia. Ponieważ Identyfikator strumienia jest teraz unikalny i nie jest ponownie używany; serwer rozpoznaje, że klient zmienił adres IP, ponownie wysyła utracone pakiety i kontynuuje komunikację pod nowym adresem.

Po czwarte, QUIC jest wdrażany na poziomie aplikacji, a nie systemu operacyjnego. To z jednej strony pozwala na szybkie wprowadzenie zmian w protokole, bo Aby uzyskać aktualizację, wystarczy zaktualizować bibliotekę, zamiast czekać na nową wersję systemu operacyjnego. Z drugiej strony prowadzi to do silnego wzrostu zużycia procesora.

I na koniec nagłówki. Kompresja nagłówka to jedna z rzeczy, które różnią się między QUIC i gQUIC. Nie widzę sensu poświęcać temu aż tak dużo czasu, powiem tylko, że w wersji przekazanej do standaryzacji kompresja nagłówków została wykonana możliwie najbardziej podobnie do kompresji nagłówków w HTTP/2. Możesz przeczytać więcej tutaj.

O ile jest szybszy?

To trudne pytanie. Faktem jest, że dopóki nie mamy standardu, nie ma nic specjalnego do zmierzenia. Być może jedyne statystyki, jakie posiadamy, to statystyki z Google, który korzysta z gQUIC od 2013 i 2016 roku zgłoszone do IETFże około 90% ruchu kierowanego do ich serwerów z przeglądarki Chrome korzysta obecnie z QUIC. W tej samej prezentacji podają, że strony ładują się około 5% szybciej przez gQUIC, a przy przesyłaniu strumieniowym wideo występuje o 30% mniej zacięć w porównaniu z TCP.

W 2017 roku grupa badaczy pod przewodnictwem Arasha Molaviego Kakhkiego opublikowała publikację dobra robota aby zbadać wydajność gQUIC w porównaniu z TCP.
Badanie ujawniło kilka słabych punktów gQUIC, takich jak niestabilność mieszania pakietów sieciowych, zachłanność (nieuczciwość) przepustowości kanału i wolniejszy transfer małych (do 10 kb) obiektów. To drugie można jednak skompensować za pomocą 0-RTT. We wszystkich pozostałych zbadanych przypadkach gQUIC wykazało wzrost prędkości w porównaniu z TCP. Trudno tu mówić o konkretnych liczbach. Lepiej przeczytaj samo badanie lub krótki post.

W tym miejscu należy powiedzieć, że dane te dotyczą konkretnie gQUIC i nie mają znaczenia dla opracowywanego standardu. Co stanie się z QUIC: to wciąż tajemnica, ale jest nadzieja, że ​​słabości zidentyfikowane w gQUIC zostaną wzięte pod uwagę i poprawione.

Kawałek przyszłości: co z HTTP/3?

Ale tutaj wszystko jest krystalicznie jasne: API nie ulegnie żadnym zmianom. Wszystko pozostanie dokładnie takie samo, jak było w HTTP/2. Cóż, jeśli API pozostanie takie samo, przejście na HTTP/3 będzie musiało zostać rozwiązane poprzez użycie nowej wersji biblioteki na backendie, która obsługuje transport QUIC. To prawda, że ​​​​będziesz musiał przez dłuższy czas korzystać ze starych wersji protokołu HTTP, ponieważ Internet nie jest obecnie gotowy na całkowite przejście na protokół UDP.

Kto już wspiera

tutaj jest lista istniejące wdrożenia QUIC. Mimo braku standardu zestawienie nie jest złe.

Żadna przeglądarka nie obsługuje obecnie QUIC w wersji produkcyjnej. Niedawno pojawiła się informacja, że ​​obsługa HTTP/3 została dodana w Chrome, ale na razie tylko w Canary.

Z backendów obsługuje tylko HTTP/3 Nosiciel kijów golfowych и Cloudflare, ale wciąż eksperymentalny. NGINX pod koniec wiosny 2019 ogłosił, że rozpoczęli pracę nad obsługą protokołu HTTP/3, ale jeszcze jej nie ukończyli.

Jakie są problemy?

Ty i ja żyjemy w prawdziwym świecie, w którym żadna wielka technologia nie może dotrzeć do mas bez napotkania oporu, a QUIC nie jest wyjątkiem.

Najważniejsze jest to, że trzeba jakoś wytłumaczyć przeglądarce, że „https://” nie jest już faktem, że prowadzi do portu TCP 443. Może w ogóle nie być protokołu TCP. Służy do tego nagłówek Alt-Svc. Pozwala poinformować przeglądarkę, że ta strona internetowa jest również dostępna na takim a takim protokole pod takim a takim adresem. W teorii powinno to działać jak urok, jednak w praktyce spotkamy się z faktem, że UDP można np. zablokować na zaporze sieciowej, aby uniknąć ataków DDoS.

Ale nawet jeśli protokół UDP nie jest zabroniony, klient może znajdować się za routerem NAT skonfigurowanym do utrzymywania sesji TCP według adresu IP, a ponieważ używamy protokołu UDP, który nie ma sesji sprzętowej, NAT nie utrzyma połączenia i sesji QUIC będzie stale zrywać.

Wszystkie te problemy wynikają z faktu, że protokół UDP nie był wcześniej używany do przesyłania treści internetowych, a producenci sprzętu nie mogli przewidzieć, że kiedykolwiek to nastąpi. W ten sam sposób administratorzy jeszcze tak naprawdę nie rozumieją, jak poprawnie skonfigurować swoje sieci, aby QUIC działał. Sytuacja ta będzie się stopniowo zmieniać, a w każdym razie takie zmiany zajmą mniej czasu niż wdrożenie nowego protokołu warstwy transportowej.

Dodatkowo, jak już opisano, QUIC znacznie zwiększa wykorzystanie procesora. Daniela Stenberga doceniane wzrost procesora aż do trzykrotnego.

Kiedy pojawi się protokół HTTP/3?

Standard chcę zaakceptować do maja 2020 r., ale biorąc pod uwagę, że dokumenty zaplanowane na lipiec 2019 r. nie są jeszcze ukończone, można powiedzieć, że najprawdopodobniej termin ten zostanie przesunięty.

Cóż, Google korzysta z implementacji gQUIC od 2013 roku. Jeśli spojrzysz na żądanie HTTP wysyłane do wyszukiwarki Google, zobaczysz to:
HTTP/3: Przełamywanie ziemi i Nowy wspaniały świat

odkrycia

QUIC wygląda obecnie na dość prymitywną, ale bardzo obiecującą technologię. Biorąc pod uwagę, że przez ostatnie 20 lat wszelkie optymalizacje protokołów warstwy transportowej dotyczyły głównie protokołu TCP, QUIC, który w większości przypadków ma najlepszą wydajność, wygląda już wyjątkowo dobrze.

Jednakże nadal istnieją nierozwiązane problemy, którymi trzeba będzie się zająć w ciągu najbliższych kilku lat. Proces może się opóźnić ze względu na zaangażowanie sprzętu, którego nikt nie lubi aktualizować, niemniej jednak wszystkie problemy wydają się całkiem możliwe do rozwiązania i prędzej czy później wszyscy będziemy mieli HTTP/3.

Przyszłość jest tuż za rogiem!

Źródło: www.habr.com

Dodaj komentarz