I mere end 20 år har vi set websider ved hjælp af HTTP-protokollen. De fleste brugere tænker ikke engang over, hvad det er, og hvordan det virker. Andre ved, at der et eller andet sted under HTTP er TLS, og under det er TCP, hvorunder er IP, og så videre. Og atter andre - kættere - mener, at TCP hører fortiden til; de vil have noget hurtigere, mere pålideligt og sikkert. Men i deres forsøg på at opfinde en ny ideel protokol er de vendt tilbage til 80'ernes teknologi og forsøger at bygge deres modige nye verden på den.

En lille historie: HTTP/1.1
I 1997 erhvervede tekstinformationsudvekslingsprotokollen HTTP version 1.1 sin egen RFC. På det tidspunkt var protokollen blevet brugt af browsere i flere år, og den nye standard holdt endnu femten. Protokollen fungerede kun efter anmodning-svar-princippet og var hovedsageligt beregnet til transmission af tekstinformation.
HTTP blev designet til at køre oven på TCP-protokollen og sikre, at pakker leveres pålideligt til deres destination. TCP fungerer ved at etablere og vedligeholde en pålidelig forbindelse mellem endepunkter og opdele trafikken i segmenter. Segmenter har deres eget serienummer og kontrolsum. Hvis et af segmenterne pludselig ikke ankommer eller ankommer med en forkert kontrolsum, stopper transmissionen, indtil det tabte segment er gendannet.
I HTTP/1.0 blev TCP-forbindelsen lukket efter hver anmodning. Dette var ekstremt spild, fordi... etablering af en TCP-forbindelse (3-Way-Handshake) er en langsom proces. HTTP/1.1 introducerede keep-alive-mekanismen, som giver dig mulighed for at genbruge én forbindelse til flere anmodninger. Men da det nemt kan blive en flaskehals, giver forskellige implementeringer af HTTP/1.1 mulighed for at åbne flere TCP-forbindelser til den samme vært. For eksempel tillader Chrome og nyere versioner af Firefox op til seks forbindelser.

Kryptering skulle også overlades til andre protokoller, og til dette blev TLS-protokollen brugt over TCP, som pålideligt beskyttede dataene, men yderligere øgede den tid, der krævedes for at etablere en forbindelse. Som et resultat begyndte håndtryksprocessen at se sådan ud:

Cloudflare illustration
HTTP/1.1 havde således en række problemer:
- Langsom forbindelsesopsætning.
- Data overføres i tekstform, hvilket betyder, at overførsel af billeder, videoer og anden ikke-tekstinformation er ineffektiv.
- Én TCP-forbindelse bruges til én anmodning, hvilket betyder, at andre anmodninger enten skal finde en anden forbindelse eller vente, indtil den aktuelle anmodning frigiver den.
- Kun pull-modellen understøttes. Der er intet i standarden om server-push.
- Overskrifter sendes i tekst.
Hvis server-push i det mindste implementeres ved hjælp af WebSocket-protokollen, så skulle de resterende problemer håndteres mere radikalt.
Lidt modernitet: HTTP/2
I 2012 begyndte Google at arbejde på SPDY (udtales "speedy")-protokollen. Protokollen var designet til at løse hovedproblemerne med HTTP/1.1 og skulle samtidig opretholde bagudkompatibilitet. I 2015 introducerede IETF-arbejdsgruppen HTTP/2-specifikationen baseret på SPDY-protokollen. Her er forskellene i HTTP/2:
- Binær serialisering.
- Multiplexing af flere HTTP-anmodninger til en enkelt TCP-forbindelse.
- Server-skub ud af æsken (uden WebSocket).
Protokollen var et stort skridt fremad. Han stærkt og kræver ikke oprettelse af flere TCP-forbindelser: alle anmodninger til én vært multiplekses til én. Det vil sige, at der i den ene forbindelse er flere såkaldte streams, som har hver sit ID. Bonussen er et server-push i boks.
Men multipleksing fører til et andet nøgleproblem. Forestil dig, at vi asynkront udfører 5 anmodninger til én server. Når du bruger HTTP/2, vil alle disse anmodninger blive udført inden for den samme TCP-forbindelse, hvilket betyder, at hvis et af segmenterne i en anmodning går tabt eller modtages forkert, vil transmissionen af alle anmodninger og svar stoppe, indtil det tabte segment er restaureret. Jo dårligere forbindelseskvaliteten er, jo langsommere virker HTTP/2. , under forhold, hvor tabte pakker udgør 2% af alle pakker, klarer HTTP/1.1 i browseren sig bedre end HTTP/2 på grund af det faktum, at den åbner 6 forbindelser frem for én.
Dette problem kaldes "head-of-line blokering", og det er desværre ikke muligt at løse det, når du bruger TCP.

Illustration af Daniel Steinberg
Som et resultat gjorde udviklerne af HTTP/2-standarden et godt stykke arbejde og gjorde næsten alt, hvad der kunne gøres på OSI-modellens applikationslag. Det er tid til at gå ned i transportlaget og opfinde en ny transportprotokol.
Vi har brug for en ny protokol: UDP vs TCP
Ret hurtigt blev det klart, at implementering af en helt ny transportlagsprotokol er en umulig opgave i nutidens realiteter. Faktum er, at hardware eller mellembokse (routere, firewalls, NAT-servere...) kender til transportlaget, og at lære dem noget nyt er en ekstremt vanskelig opgave. Derudover er understøttelse af transportprotokoller indbygget i kernen af operativsystemer, og kerner er heller ikke særlig villige til at ændre sig.
Og her kunne man kaste hænderne op og sige “Vi vil selvfølgelig opfinde en ny HTTP/3 med præference og kurtisaner, men det vil tage 10-15 år at blive implementeret (efter ca. dette tidspunkt vil det meste af hardwaren være erstattet), men der er en mere ikke så Den oplagte mulighed er at bruge UDP-protokollen. Ja, ja, den samme protokol, som vi brugte til at smide filer over LAN i slutningen af halvfemserne og begyndelsen af XNUMX'erne. Næsten al nutidens hardware kan arbejde med det.
Hvad er fordelene ved UDP frem for TCP? Først og fremmest har vi ikke en transportlagssession, som hardwaren kender til. Dette giver os mulighed for selv at bestemme sessionen på endepunkterne og løse konflikter der. Det vil sige, at vi ikke er begrænset til en eller flere sessioner (som i TCP), men kan oprette lige så mange af dem, som vi har brug for. For det andet er datatransmission via UDP hurtigere end via TCP. Således kan vi i teorien bryde igennem det nuværende hastighedsloft opnået i HTTP/2.
UDP garanterer dog ikke pålidelig dataoverførsel. Faktisk sender vi simpelthen pakker i håb om, at den anden ende vil modtage dem. Har ikke modtaget? Nå, uden held... Dette var nok til at overføre videoer til voksne, men for mere seriøse ting har du brug for pålidelighed, hvilket betyder, at du skal indpakke noget andet oven på UDP.
Ligesom med HTTP/2 begyndte arbejdet med at skabe en ny protokol hos Google i 2012, det vil sige omtrent samtidig med at arbejdet med SPDY begyndte. I 2013 præsenterede Jim Roskind for den brede offentlighed , og allerede i 2015 blev Internet Draft introduceret til standardisering i IETF. Allerede på det tidspunkt var protokollen udviklet af Roskind hos Google meget forskellig fra standarden, så Google-versionen begyndte at blive kaldt gQUIC.
Hvad er QUIC
For det første, som allerede nævnt, er dette en indpakning over UDP. En QUIC-forbindelse stiger oven på UDP, hvor der analogt med HTTP/2 kan eksistere flere streams. Disse streams findes kun på endepunkterne og serveres uafhængigt. Hvis der opstår et pakketab i én strøm, vil det ikke påvirke andre.

Illustration af Daniel Steinberg
For det andet implementeres kryptering ikke længere på et separat niveau, men er inkluderet i protokollen. Dette giver dig mulighed for at etablere en forbindelse og udveksle offentlige nøgler i et enkelt håndtryk, og giver dig også mulighed for at bruge den smarte 0-RTT-håndtryksmekanisme og helt undgå håndtryksforsinkelser. Derudover er det nu muligt at kryptere individuelle datapakker. Dette giver dig mulighed for ikke at vente på færdiggørelsen af at modtage data fra strømmen, men at dekryptere de modtagne pakker uafhængigt. Denne driftsform var generelt umulig i TCP, fordi TLS og TCP arbejdede uafhængigt af hinanden, og TLS kunne ikke vide, hvilke stykker TCP-data ville blive hugget. Og derfor kunne han ikke forberede sine segmenter, så de passede ind i TCP-segmenter en til en og kunne dekrypteres uafhængigt. Alle disse forbedringer gør det muligt for QUIC at reducere latens sammenlignet med TCP.

For det tredje giver begrebet lysstreaming dig mulighed for at afkoble forbindelsen fra klientens IP-adresse. Dette er vigtigt, for eksempel når en klient skifter fra et Wi-Fi-adgangspunkt til et andet og ændrer dets IP. I dette tilfælde, når du bruger TCP, sker der en langvarig proces, hvor eksisterende TCP-forbindelser timeout, og nye forbindelser oprettes fra en ny IP. I tilfælde af QUIC fortsætter klienten simpelthen med at sende pakker til serveren fra en ny IP med det gamle stream-id. Fordi Stream-id'et er nu unikt og genbruges ikke; serveren forstår, at klienten har ændret IP, sender mistede pakker igen og fortsætter kommunikationen på den nye adresse.
For det fjerde implementeres QUIC på applikationsniveau, ikke på operativsystemniveau. Dette giver dig på den ene side mulighed for hurtigt at foretage ændringer i protokollen, pga For at få en opdatering skal du bare opdatere biblioteket i stedet for at vente på en ny OS-version. På den anden side fører dette til en kraftig stigning i processorforbruget.
Og endelig overskrifterne. Header-komprimering er en af de ting, der adskiller sig mellem QUIC og gQUIC. Jeg kan ikke se meningen med at bruge meget tid på dette, jeg vil bare sige, at i den version, der blev sendt til standardisering, blev header-komprimering lavet så lig som muligt med header-komprimering i HTTP/2. Du kan læse mere .
Hvor meget hurtigere er det?
Det er et svært spørgsmål. Faktum er, at indtil vi har en standard, er der ikke noget særligt at måle. Måske er den eneste statistik, vi har, statistik fra Google, som har brugt gQUIC siden 2013 og i 2016 at omkring 90 % af trafikken, der går til deres servere fra Chrome-browseren, nu bruger QUIC. I samme præsentation rapporterer de, at sider indlæses omkring 5 % hurtigere gennem gQUIC, og der er 30 % færre hakkere i videostreaming sammenlignet med TCP.
I 2017 offentliggjorde en gruppe forskere ledet af Arash Molavi Kakhki at studere ydeevnen af gQUIC sammenlignet med TCP.
Undersøgelsen afslørede adskillige svagheder ved gQUIC, såsom ustabilitet i forbindelse med blanding af netværkspakker, grådighed (uretfærdighed) til kanalbåndbredde og langsommere overførsel af små (op til 10 kb) objekter. Sidstnævnte kan der dog kompenseres for ved at bruge 0-RTT. I alle andre undersøgte tilfælde viste gQUIC en stigning i hastighed sammenlignet med TCP. Det er svært at tale om specifikke tal her. Bedre læse eller .
Her skal det siges, at disse data specifikt handler om gQUIC, og det er ikke relevant for den standard, der udvikles. Hvad vil der ske for QUIC: det er stadig en hemmelighed, men der er håb om, at svaghederne identificeret i gQUIC vil blive taget i betragtning og rettet.
Lidt om fremtiden: hvad med HTTP/3?
Men her er alt krystalklart: API'et vil ikke ændre sig på nogen måde. Alt forbliver nøjagtigt det samme, som det var i HTTP/2. Nå, hvis API'et forbliver det samme, skal overgangen til HTTP/3 løses ved at bruge en frisk version af biblioteket på backend, der understøtter QUIC-transport. Sandt nok bliver du nødt til at beholde tilbagefaldet på gamle versioner af HTTP i et stykke tid, fordi Internettet er i øjeblikket ikke klar til en fuldstændig overgang til UDP.
Som allerede støtter
her eksisterende QUIC implementeringer. På trods af manglen på en standard er listen ikke dårlig.
Ingen browser understøtter i øjeblikket QUIC i en produktionsudgivelse. For nylig var der oplysninger om, at understøttelse af HTTP/3 var inkluderet i Chrome, men indtil videre kun på Canary.
Af backends understøtter HTTP/3 kun и , men stadig eksperimenterende. NGINX i slutningen af foråret 2019 , at de begyndte at arbejde på HTTP/3-understøttelse, men ikke er færdige med det endnu.
Hvad er problemerne?
Du og jeg lever i den virkelige verden, hvor ingen stor teknologi kan nå ud til masserne uden at møde modstand, og QUIC er ingen undtagelse.
Det vigtigste er, at du på en eller anden måde skal forklare browseren, at "https://" ikke længere er et faktum, at det fører til TCP-port 443. Der er muligvis slet ikke TCP. Alt-Svc-headeren bruges til dette. Det giver dig mulighed for at fortælle browseren, at denne hjemmeside også er tilgængelig på sådan en protokol på sådan en adresse. I teorien skulle dette virke som en charme, men i praksis vil vi støde på, at UDP for eksempel kan forbydes på en firewall for at undgå DDoS-angreb.
Men selvom UDP ikke er forbudt, kan klienten stå bag en NAT-router, der er konfigureret til at holde en TCP-session efter IP-adresse, og da vi bruger UDP, som ikke har nogen hardware-session, NAT holder ikke forbindelsen, og en QUIC-session .
Alle disse problemer skyldes, at UDP ikke tidligere var blevet brugt til at overføre internetindhold, og hardwareproducenter kunne ikke forudse, at dette nogensinde ville ske. På samme måde forstår administratorer endnu ikke rigtig, hvordan de konfigurerer deres netværk korrekt, så QUIC kan fungere. Denne situation vil gradvist ændre sig, og under alle omstændigheder vil sådanne ændringer tage kortere tid end implementeringen af en ny transportlagsprotokol.
Derudover, som allerede beskrevet, øger QUIC i høj grad CPU-forbruget. Daniel Stenberg processorvækst op til tre gange.
Hvornår kommer HTTP/3?
Standard i maj 2020, men i betragtning af at dokumenter, der er planlagt til juli 2019, forbliver ufærdige i øjeblikket, kan vi sige, at datoen højst sandsynligt vil blive rykket tilbage.
Nå, Google har brugt sin gQUIC-implementering siden 2013. Hvis du ser på HTTP-anmodningen, der sendes til Google-søgemaskinen, vil du se dette:

Fund
QUIC ligner nu en ret rå, men meget lovende teknologi. I betragtning af, at alle optimeringer af transportlagsprotokoller i de seneste 20 år hovedsageligt har vedrørt TCP, ser QUIC, som i de fleste tilfælde har den bedste ydeevne, allerede særdeles godt ud.
Der er dog stadig uløste problemer, som skal håndteres i de næste par år. Processen kan blive forsinket på grund af, at der er hardware involveret, som ingen kan lide at opdatere, men ikke desto mindre ser alle problemerne ret løselige ud, og før eller siden vil vi alle have HTTP/3.
Fremtiden er lige rundt om hjørnet!
Kilde: www.habr.com
