HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld

Al meer dan 20 jaar bekijken we webpagina's via het HTTP-protocol. De meeste gebruikers denken er helemaal niet over na wat het is en hoe het werkt. Anderen weten dat er ergens onder HTTP TLS is, en daaronder TCP, daaronder IP, en zo verder. En sommigen – ketters – beschouwen TCP als verouderd en willen iets snelers, betrouwbaarders en veiliger. Maar in hun pogingen om een nieuwe ideale protocol uit te vinden, zijn ze teruggekeerd naar technologieën uit de jaren '80 en proberen ze daar hun wonderlijke nieuwe wereld op te bouwen.
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld

Een beetje geschiedenis: HTTP/1.1

In 1997 kreeg het tekstuitwisselingsprotocol HTTP versie 1.1 zijn RFC. Op dat moment werd het protocol al enkele jaren door browsers gebruikt, en de nieuwe standaard hield het nog vijftien jaar vol. Het protocol werkte uitsluitend volgens het verzoek-antwoordprincipe en was voornamelijk bedoeld voor het verzenden van tekstuele informatie.

HTTP is ontworpen om bovenop het TCP-protocol te functioneren, dat een betrouwbare aflevering van pakketten aan de bestemming garandeert. TCP werkt door het opzetten en onderhouden van een betrouwbare verbinding tussen eindpunten en het opdelen van verkeer in segmenten. Segmenten hebben een volgnummer en een controlegetal. Als een van de segmenten niet aankomt of met een onjuist controlegetal arriveert, stopt de overdracht totdat het ontbrekende segment is hersteld.

In HTTP/1.0 werd de TCP-verbinding na elk verzoek gesloten. Dit was uiterst on efficiënt, omdat het opzetten van een TCP-verbinding (3-Way-Handshake) een traag proces is. In HTTP/1.1 werd het keep-alive-mechanisme geïntroduceerd, waarmee één verbinding voor meerdere verzoeken kan worden hergebruikt. Omdat dit echter gemakkelijk een bottleneck kan worden, staan verschillende implementaties van HTTP/1.1 het openen van meerdere TCP-verbindingen naar één host toe. Bijvoorbeeld, in Chrome en de recentste versies van Firefox zijn er tot zes verbindingen toegestaan.
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld
Versleuteling werd ook bedoeld om aan andere protocollen te worden toevertrouwd, en daarvoor werd het TLS-protocol bovenop TCP gebruikt, dat de gegevens behoorlijk veilig beschermde, maar de tijd die nodig was om een verbinding op te zetten, nog verder verhoogde. Uiteindelijk zag het handshake-proces er als volgt uit:
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld
Illustratie Cloudflare

HTTP/1.1 had dus een aantal problemen:

  • Trage opzet van de verbinding.
  • Gegevens worden in tekstformaat verzonden, wat betekent dat het verzenden van afbeeldingen, video's en andere niet-tekstuele informatie niet efficiënt is.
  • Één TCP-verbinding wordt gebruikt voor één verzoek, wat betekent dat andere verzoeken ofwel een andere verbinding moeten vinden, of moeten wachten totdat het huidige verzoek deze vrijgeeft.
  • Alleen het pull-model wordt ondersteund. In de standaard staat niets over server-push.
  • Koppen worden als tekst verzonden.

Als server-push met enige moeite wordt geïmplementeerd via het WebSocket-protocol, moesten de andere problemen radicaler worden aangepakt.

Een beetje moderniteit: HTTP/2

In 2012 begon Google te werken aan het SPDY-protocol (uitgesproken als 'speedy'). Dit protocol was ontworpen om de belangrijkste problemen van HTTP/1.1 op te lossen, terwijl het ook de achterwaartse compatibiliteit moest waarborgen. In 2015 presenteerde de IETF-werkgroep de specificatie van HTTP/2, gebaseerd op het SPDY-protocol. Dit zijn de verschillen in HTTP/2:

  • Binaire serialisatie.
  • Multiplexing van meerdere HTTP-verzoeken binnen één TCP-verbinding.
  • Server-push out-of-the-box (zonder WebSocket).

Het protocol betekende een grote sprong voorwaarts. Het wint aanzienlijk aan snelheid ten opzichte van de eerste versie en vereist geen meerdere TCP-verbindingen: alle verzoeken naar één host worden gemultiplexed in één verbinding. Dit betekent dat er binnen één verbinding meerdere zogeheten streams zijn, elk met zijn eigen ID. Als bonus is er server-push ingebouwd.

Echter, multiplexing leidt tot een ander cruciaal probleem. Stel je voor dat we asynchroon 5 verzoeken naar dezelfde server uitvoeren. Bij het gebruik van HTTP/2 worden al deze verzoeken uitgevoerd binnen één TCP-verbinding, en als een van de segmenten van een verzoek verloren gaat of incorrect aankomt, wordt de overdracht van alle verzoeken en antwoorden stopgezet totdat het verloren segment is hersteld. Het is duidelijk dat hoe slechter de kwaliteit van de verbinding, hoe langzamer HTTP/2 werkt. Volgens Daniel Stenberg, toont HTTP/1.1 zich beter in omstandigheden waarin verloren pakketten 2% van alles uitmaken, omdat het 6 verbindingen opent in plaats van één.

Dit probleem wordt 'head-of-line blocking' genoemd en helaas is het niet mogelijk om dit op te lossen met TCP.
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld
Illustratie Daniel Steinberg

Als resultaat hebben de ontwikkelaars van de standaard HTTP/2 enorm veel werk verricht en bijna alles gedaan wat mogelijk was op het toepassingsniveau van het OSI-model. Het is tijd om naar het transportniveau te dalen en een nieuw transportprotocol uit te vinden.

We hebben een nieuw protocol nodig: UDP vs TCP

Het werd al snel duidelijk dat het implementeren van een geheel nieuw transportprotocol in de huidige realiteit een onoplosbare taak is. Het probleem is dat de hardware of middle-boxes (routers, firewalls, NAT-servers...) kennis heeft van het transportniveau, en het is een zeer uitdagende taak om ze iets nieuws te leren. Bovendien is de ondersteuning voor transportprotocollen ingebouwd in de kernels van besturingssystemen, en ook die veranderen niet zomaar.

En hier zou je je handen kunnen laten hangen en zeggen: "Natuurlijk zullen we een nieuwe HTTP/3 uitvinden met voorkeuren en courtisanes, maar het zal 10-15 jaar duren voordat deze is geïmplementeerd (ongeveer in die tijd zullen de meeste apparaten zijn vervangen)", maar er is nog een niet zo voor de hand liggende optie: gebruik het UDP-protocol. Ja, datzelfde protocol waarmee we aan het einde van de jaren negentig en het begin van de jaren 2000 bestandjes over het lokale netwerk gooiden. Praktisch alle huidige apparaten kunnen ermee werken.

Wat zijn de voordelen van UDP ten opzichte van TCP? In de eerste plaats dat we geen transportniveau-sessie hebben waar de hardware van weet. Dit stelt ons in staat om zelf de sessie op de eindpunten te bepalen en daar ook de conflicten op te lossen die ontstaan. Dat wil zeggen dat we niet gebonden zijn aan één of meerdere sessies (zoals bij TCP), maar we zoveel sessies kunnen creëren als we nodig hebben. Ten tweede vindt de gegevensoverdracht via UDP sneller plaats dan via TCP. Theoretisch kunnen we dus de huidige snelheidslimiet die we in HTTP/2 hebben bereikt, doorbreken.

Echter, UDP garandeert geen betrouwbaarheid van gegevensoverdracht. In feite sturen we gewoon pakketten en hopen we dat ze aan de andere kant worden ontvangen. Niet ontvangen? Jammer dan... Dit was voldoende voor het verzenden van video's voor volwassenen, maar voor serieuzere dingen is betrouwbaarheid nodig, wat betekent dat we nog iets bovenop UDP moeten bouwen.

Net als bij HTTP/2 begon het werk aan het nieuwe protocol in 2012 bij Google, dat is ongeveer rond dezelfde tijd als de start van het werk aan SPDY. In 2013 presenteerde Jim Roskind het brede publiek het QUIC-protocol (Quick UDP Internet Connections), en in 2015 werd er een Internet Draft ingediend voor standaardisatie bij de IETF. Op dat moment verschilde het door Roskind bij Google ontwikkelde protocol aanzienlijk van het voorgestelde standaard, waardoor de Google-versie gQUIC werd genoemd.

Wat is QUIC

Ten eerste, zoals eerder vermeld, is het een wrapper bovenop UDP. Bovenop UDP wordt een QUIC-verbinding opgezet, waarin net als bij HTTP/2 meerdere streams kunnen bestaan. Deze streams bestaan alleen op de eindpunten en worden onafhankelijk behandeld. Als er een pakketverlies optreedt in één stream, heeft dat geen invloed op de andere.
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld
Illustratie Daniel Steinberg

Ten tweede wordt encryptie nu niet als een apart niveau gerealiseerd, maar is het geïntegreerd in het protocol. Dit maakt het mogelijk om een verbinding tot stand te brengen en publieke sleutels uit te wisselen met één handdruk, en het stelt ons in staat om het slimme mechanisme van 0-RTT handshake te gebruiken en überhaupt vertragingen bij de handshake te vermijden. Bovendien kunnen nu afzonderlijke datapakketten gecodeerd worden. Dit maakt het mogelijk om niet te wachten op het afsluiten van gegevensontvangst uit de stream, maar ontvangen pakketten onafhankelijk te ontsleutelen. Zo'n werkwijze was in TCP helemaal niet mogelijk, omdat TLS en TCP onafhankelijk van elkaar werkten en TLS niet kon weten in welke stukken TCP de gegevens zouden worden verdeeld. En dus kon het geen segmenten voorbereiden die precies in de TCP-segmenten pasten en onafhankelijk konden worden ontsleuteld. Al deze verbeteringen stellen QUIC in staat om de latentie te verlagen in vergelijking met TCP.
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld
Ten derde maakt het concept van lichte streams het mogelijk om de verbinding los te koppelen van het IP-adres van de client. Dit is bijvoorbeeld belangrijk wanneer de client van het ene Wi-Fi-toegangspunt naar een ander schakelt, waarbij zijn IP verandert. In dit geval vindt er bij gebruik van TCP een langdurig proces plaats, waarin bestaande TCP-verbindingen tijdig worden verbroken en nieuwe verbindingen worden aangemaakt met het nieuwe IP. In het geval van QUIC blijft de client gewoon pakketten naar de server sturen vanaf het nieuwe IP met de oude stream-ID. Aangezien de stream-ID nu uniek is en niet opnieuw wordt gebruikt, begrijpt de server dat de client van IP is veranderd, stuurt verloren pakketten opnieuw en gaat de communicatie op het nieuwe adres verder.

Ten vierde wordt QUIC op toepassingsniveau geïmplementeerd en niet op het niveau van het besturingssysteem. Dit maakt het aan de ene kant mogelijk om sneller wijzigingen in het protocol door te voeren, omdat het voldoende is om de bibliotheek bij te werken in plaats van te wachten op een nieuwe versie van het besturingssysteem. Aan de andere kant leidt dit tot een sterke toename van het CPU-gebruik.

Dan de headers. Headercompressie is precies zo'n aspect dat verschilt tussen QUIC en gQUIC. Ik zie niet in waarom we hier veel tijd aan zouden moeten besteden, ik zeg alleen dat in de versie die ter standaardisatie is ingediend, de headercompressie zo veel mogelijk gelijk is gemaakt aan die van HTTP/2. Meer details zijn te lezen. hier.

Hoeveel sneller is het?

Dit is een complexe vraag. Het probleem is dat we op dit moment geen standaard hebben, dus er is niet veel te meten. De enige statistieken die we hebben, zijn die van Google, dat gQUIC sinds 2013 gebruikt en in 2016 voor de IETF verslag heeft uitgebracht,, dat ongeveer 90% van het verkeer naar hun servers vanuit de Chrome-browser nu QUIC gebruikt. In dezelfde presentatie geven ze aan dat pagina's via gQUIC ongeveer 5% sneller laden, terwijl er bij streamingvideo's 30% minder haperingen zijn in vergelijking met TCP.

In 2017 publiceerde een groep onderzoekers onder leiding van Arash Molavi Kakhki veel werk een studie over de prestaties van gQUIC in vergelijking met TCP.
Het onderzoek heeft verschillende zwakke punten van gQUIC aan het licht gebracht, zoals kwetsbaarheid voor netwerkpakketvermeandering, hebzucht (unfairness) met betrekking tot de kanaalcapaciteit en tragere overdracht van kleine (tot 10 kB) objecten. Dit laatste kan overigens gecompenseerd worden met 0-RTT. In alle andere onderzochte gevallen toonde gQUIC een snelheidstoename in vergelijking met TCP. Over specifieke cijfers hier praten is moeilijk. Het is beter om de studie zelf of een korte post.

Hier moet worden vermeld dat dit gegevens zijn over gQUIC en zij zijn niet relevant voor de momenteel ontwikkelde standaard. Wat er met QUIC zal gebeuren, blijft voorlopig een raadsel, maar er is hoop dat de zwakke punten die in gQUIC zijn vastgesteld, zullen worden aangepakt en gecorrigeerd.

Een beetje toekomstmuziek: en wat met HTTP/3?

Hier is alles kristalhelder: de API zal niet veranderen. Alles blijft precies zoals het was in HTTP/2. En als de API hetzelfde blijft, moet de overstap naar HTTP/3 worden gemaakt door de nieuwste versie van de bibliotheek aan de backend te gebruiken, die transport via QUIC ondersteunt. Het zal echter nog geruime tijd duren voordat er een fallback naar oudere versies van HTTP nodig is, omdat het internet momenteel niet klaar is voor een volledige overstap naar UDP.

Wie ondersteunt al

Hier is de lijst bestaande QUIC-implementaties. Ondanks het gebrek aan een standaard, is de lijst niet slecht.

Geen enkele browser ondersteunt momenteel QUIC in een productieversie. Recent was er informatie dat Chrome ondersteuning voor HTTP/3 heeft ingeschakeld, maar alleen in Canary.

Van de backends ondersteunt alleen Caddy en Cloudflare, maar momenteel experimenteel. NGINX heeft eind lente 2019 de aanvang aan van de distributie van het laatste blok /8. Vanaf dat moment kon elke klant van de registrar slechts 1024 adressen verkrijgen, wat de uitputting van de voorraad enigszins vertraagde. Maar in 2015 had RIPE nog 16 miljoen beschikbare IP-adressen, en in de zomer van 2019 was dit aantal gedaald, bekendgemaakt dat ze werken aan ondersteuning voor HTTP/3, maar dat is nog niet afgerond.

Welke problemen zijn er

We leven in een echte wereld waar geen enkele grote technologie populair kan worden zonder weerstand te ondervinden, en QUIC is daarop geen uitzondering.

Het belangrijkste is dat je de browser moet uitleggen dat "https://" nu niet noodzakelijk naar poort 443 TCP leidt. TCP kan daar zelfs helemaal niet zijn. Dit wordt gedaan met de Alt-Svc-header. Hiermee kan de browser worden geïnformeerd dat deze website ook beschikbaar is op een ander protocol op een bepaald adres. In theorie zou dit als een klok moeten werken, maar in de praktijk stuiten we op het feit dat UDP bijvoorbeeld geblokkeerd kan zijn op de firewall om DDoS-aanvallen te voorkomen.

Maar zelfs als UDP niet is geblokkeerd, kan de client zich achter een NAT-router bevinden, die is ingesteld om TCP-sessies vast te houden op IP-adres, en omdat we UDP gebruiken, dat geen hardware sessie heeft, zal NAT de verbinding niet behouden, en zal de QUIC-sessie constant worden onderbroken.

Al deze problemen zijn gerelateerd aan het feit dat UDP vroeger niet werd gebruikt voor het verzenden van internetinhoud, en hardwarefabrikanten konden niet voorzien dat dit ooit zou gebeuren. Evenzo begrijpen beheerders tot nu toe niet goed hoe ze hun netwerken correct kunnen configureren om met QUIC te werken. Deze situatie zal langzaam veranderen, en in ieder geval zullen soortgelijke veranderingen minder tijd kosten dan de implementatie van een nieuw transportprotocol.

Bovendien, zoals al beschreven, verhoogt QUIC het CPU-gebruik aanzienlijk. Daniel Stenberg schatte de groei in CPU-gebruik tot drie keer.

Wanneer komt HTTP/3

De standaard willen ze aannemen In mei 2020, maar gezien het feit dat de documenten die voor juli 2019 gepland waren momenteel nog niet af zijn, kan worden gezegd dat de datum waarschijnlijk zal worden uitgesteld.

Google gebruikt sinds 2013 zijn eigen implementatie van gQUIC. Als je de HTTP-aanroep bekijkt die naar de Google-zoekmachine wordt verzonden, zie je dit:
HTTP/3: de fundamenten ondermijnen en een wonderbaarlijke nieuwe wereld

Conclusies

QUIC lijkt nu een vrij onvolmaakte, maar zeer veelbelovende technologie. Gezien het feit dat de afgelopen 20 jaar alle optimalisaties van transportprotocols voornamelijk met TCP te maken hadden, ziet QUIC, dat meestal beter presteert, er al heel goed uit.

Echter, er blijven nog onopgeloste problemen die we de komende jaren moeten aanpakken. Het proces kan zich uitstrekken door de hardware die niemand graag bijwerkt, maar alle problemen lijken redelijk oplosbaar en vroeg of laat zullen we allemaal HTTP/3 hebben.

De toekomst is nabij!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster