Már több mint 20 éve böngészünk weboldalakat HTTP protokollon keresztül. A legtöbb felhasználó egyáltalán nem gondol arra, hogy mi ez és hogyan működik. Mások tudják, hogy a HTTP alatt van a TLS, alatta pedig a TCP, aztán jön az IP, és így tovább. És vannak harmadik, eretnek gondolkodásúak, akik azt hiszik, hogy a TCP a múlté, és valami gyorsabbra, megbízhatóbbra és biztonságosabbra vágynak. De kísérleteikben, hogy új, tökéletes protokollt alkossanak, visszatértek a nyolcvanas évek technológiáihoz, és azon próbálnak meg felépíteni egy csodálatos új világot.

Egy kis történelem: HTTP/1.1
1997-ben az HTTP 1.1 verziója megkapta a saját RFC-jét. Abban az időben a protokollt már évek óta használták a böngészők, és az új standard további tizenöt évig érvényes maradt. A protokoll csak kérés-válasz elven működött, és főként szöveges információk átvitelére készült.
Az HTTP-t a TCP protokoll fölött tervezték, amely garantálja a csomagok megbízható kézbesítését a címzettnek. A TCP működése a végpontok közötti megbízható kapcsolat létrehozásán és fenntartásán alapul, valamint a forgalom szegmensekre bontásán. A szegmenseknek van sorozatszámuk és ellenőrző összegük. Ha esetleg valamelyik szegmens nem érkezik meg vagy hibás ellenőrző összeggel érkezik, akkor a küldés leáll, amíg a hiányzó szegmens vissza nem tér.
A HTTP/1.0 esetében a TCP-kapcsolat minden kérdés után lezárult. Ez rendkívül pazarló volt, mivel a TCP-kapcsolat létrehozása (3-Way-Handshake) nem egy gyors folyamat. A HTTP/1.1 bevezette a keep-alive mechanizmust, amely lehetővé teszi egy kapcsolat újrahasználatát több kérdéshez. Azonban mivel ez könnyen szűk keresztmetszetté válhat, a HTTP/1.1 különböző megvalósításaiban megengedett, hogy több TCP-kapcsolat is nyitva maradjon egy hosthoz. Például a Chrome és a legújabb Firefox verziók lehetővé teszik akár hat kapcsolat létrehozását.

A titkosítást szintén más protokollokra akarták bízni, és ezért a TCP fölött a TLS protokollt kezdték alkalmazni, amely meglehetősen megbízhatóan védte az adatokat, de még inkább megnövelte a kapcsolat létrehozásához szükséges időt. Ennek eredményeként a kézfogási folyamat így nézett ki:

Cloudflare ábra
Így a HTTP/1.1 számos problémával küzdött:
- Lassú kapcsolat létrehozás.
- Az adatok szöveges formában kerülnek továbbításra, így a képek, videók és egyéb nem szöveges információk átadása nem hatékony.
- Egy TCP-kapcsolatot egy kéréshez használnak, így a többi kérésnek vagy egy másik kapcsolatot kell keresnie, vagy várnia kell, amíg a jelenlegi kérés megszabadul.
- Csak pull-modell támogatott. A szabványban nincs semmi a server-push-ról.
- A fejlécek szövegesen kerülnek továbbításra.
Ha a server-push csak valamelyest megvalósítható a WebSocket protokoll segítségével, akkor a többi problémát radikálisabban kellett kezelni.
Egy kis frissesség: HTTP/2
2012-ben a Google mélyén elkezdődött a SPDY protokoll fejlesztése (ejtsd: 'spidi'). A protokoll célja az HTTP/1.1 fő problémáinak megoldása volt, miközben meg kellett tartania a visszafelé kompatibilitást. 2015-ben az IETF munkacsoport bemutatta a HTTP/2 specifikációt, amely a SPDY protokollon alapult. Íme a HTTP/2 főbb különbségei:
- Binaries serializálása.
- Több HTTP-kérés multiplexelése egy TCP-kapcsolatba.
- Server-push dobozból (WebSocket nélkül).
A protokoll nagy előrelépést jelentett. Nagyon és nem igényel több TCP-kapcsolat létrehozását: az összes kérés egy hosthoz egybe van multiplexelve. Tehát egy kapcsolaton belül több úgynevezett stream található, mindegyik saját azonosítójával. Bónuszként jön a dobozos server-push.
A multiplexelés azonban egy másik sarokkövévé válik a problémának. Képzelje el, hogy aszinkron módon hajtunk végre 5 kérést egy szerverhez. A HTTP/2 használatakor mindez a kérések egy TCP-kapcsolaton belül történik, tehát ha bármelyik kérés szegmense elveszik vagy hibásan érkezik meg, az összes kérés és válasz továbbítása leáll, amíg az elveszett szegmens helyre nem áll. , ha a vesztes csomagok az összes csomag 2%-át teszik ki, akkor a HTTP/1.1 a böngészőben jobban teljesít, mint a HTTP/2, mivel 6 kapcsolatot nyit, nem pedig egyet.
Ezt a problémát „head-of-line blocking”-nak nevezik, és sajnos a TCP használatakor nem megoldható.

Illusztráció Daniel Steinberg
Összességében a HTTP/2 szabvány fejlesztői óriási munkát végeztek, és szinte mindent megtettek, amit csak lehetett az OSI modell alkalmazási szintjén. Itt az idő, hogy leereszkedjünk a szállítási szintre, és felfedezzünk egy új szállítási protokollt.
Szükségünk van egy új protokollra: UDP vs TCP
Elég gyorsan világossá vált, hogy egy teljesen új szállítási protokoll bevezetése a mai valóságok között megoldhatatlan feladat. Az a helyzet, hogy a szállítási szintről a hardverek vagy middle-boxok (routerek, tűzfalak, NAT szerverek…) tudnak, és nagyon nehéz őket új dolgokra megtanítani. Ezen kívül a szállítási protokollok támogatása az operációs rendszerek magjába van beépítve, és a magok sem változnak túl szívesen.
Itt le lehetne mondani, és mondani, hogy „Természetesen kitaláljuk az új HTTP/3-at, sok minden más mellett, de a bevezetése még 10-15 évbe telik (körülbelül ennyi időbe telik, mire a legtöbb hardver cserélődik)”, de van egy másik, nem annyira nyilvánvaló lehetőség: használni az UDP protokollt. Igen, igen, arra a protokollra, amivel a fájlokat küldtük a helyi hálózaton az ezredforduló környékén. Gyakorlatilag minden mai hardver tudja, hogyan kell kezelni.
Mik az UDP előnyei a TCP-vel szemben? Elsősorban az, hogy nincs szállítási szintű kapcsolat, amiről a hardver tud. Ez lehetővé teszi számunkra, hogy saját magunk határozzuk meg a kapcsolatokat a végpontokon, és ott kezeljük a felmerülő konfliktusokat. Tehát nem vagyunk korlátozva egy vagy több kapcsolatra (mint a TCP esetén), hanem annyit hozhatunk létre, amennyire szükségünk van. Másodszor, az adatok átadása UDP-n sokkal gyorsabb, mint TCP-n. Tehát elméletileg áttörhetjük a mai sebességrögzítést, amit a HTTP/2-ben elértünk.
Azonban az UDP nem garantálja az adatátvitel megbízhatóságát. Valójában csak csomagokat küldünk, bízva benne, hogy a másik végén megkapják őket. Nem kapták meg? Hát, pech… Ez elég volt felnőtt videók átadásához, de komolyabb dolgokhoz megbízhatóságra van szükség, amihez általában valamit még rá kellene építenünk az UDP-re.
A HTTP/2-höz hasonlóan az új protokoll létrehozási munkálatai a Google-nál 2012-ben kezdődtek, tehát nagyjából egy időben a SPDY fejlesztésének megkezdésével. 2013-ban Jim Roskind bemutatta a nagyközönségnek. , és 2015-ben Internet Draft került benyújtásra a IETF szabványosítása érdekében. Már akkor a Google által kifejlesztett protokoll jelentősen eltért a javasolt szabványtól, ezért a Google verzióját gQUIC-nak nevezték el.
Mi az a QUIC?
Először is, ahogy már említettem, ez egy burkolat az UDP felett. Az UDP-re épül a QUIC kapcsolat, amelyben a HTTP/2-höz hasonlóan több stream is létrejöhet. Ezek a streamek csak a végpontokon léteznek, és függetlenül működnek. Ha egy streamben csomagvesztés történik, az más streamekre nem gyakorol hatást.

Illusztráció Daniel Steinberg
Másodszor, a titkosítás most már nem külön szinten valósul meg, hanem be van építve a protokollba. Ez lehetővé teszi a kapcsolat létesítését és a nyilvános kulcsok cseréjét egyetlen kézfogás során, valamint egy ügyes 0-RTT kézfogás mechanizmus használatát, így elkerülve az késlekedéseket a kézfogásnál. Ezen kívül, lehetőség van egyes adatcsomagok titkosítására is. Ez lehetővé teszi, hogy ne várjunk az adatstream befejezésére, hanem függetlenül dekódolhassuk a megkapott csomagokat. Ez a működési mód teljesen lehetetlen volt TCP-nél, mivel a TLS és a TCP függetlenül működtek egymástól, és a TLS nem tudta, hogy a TCP milyen darabokra bontja az adatokat. Ezért nem tudta úgy előkészíteni a saját szegmenseit, hogy azok egy az egyben megfeleljenek a TCP szegmenseinek, így függetlenül nem tudtak dekódolva lenni. Mindezek a fejlesztések lehetővé teszik a QUIC számára, hogy a TCP-hez képest csökkentse a késleltetést.

Harmadszor, a könnyű streamek koncepciója lehetővé teszi a kapcsolat függetlenítését az ügyfél IP-címétől. Ez fontos például, amikor az ügyfél átvált egy másik Wi-Fi hozzáférési pontra, megváltoztatva ezzel az IP-címét. Ilyen esetben a TCP használatakor egy hosszú folyamat zajlik, amely során a meglévő TCP kapcsolatok időtúllépés miatt megszakadnak, és új kapcsolatok jönnek létre az új IP-címről. QUIC esetében az ügyfél egyszerűen folytatja a csomagok küldését a szervernek az új IP-címről, a régi stream ID-vel. Mivel a stream ID most már egyedi és nem újrahasználható, a szerver megérti, hogy az ügyfél megváltoztatta az IP-címét, újraküldi az elveszett csomagokat, és folytatja a kommunikációt az új címen.
Negyedik, a QUIC az alkalmazási szinten valósul meg, nem az operációs rendszeren. Ez egyrészt lehetővé teszi a protokoll gyorsabb módosítását, mivel ahhoz, hogy frissítést kapjunk, elég egyszerűen frissíteni a könyvtárat, nem kell várni az új operációs rendszer verzióra. Másrészt azonban ez a CPU-felhasználás jelentős növekedéséhez vezet.
Nos, a végére maradtak a fejlécek. A fejléc tömörítés éppen az a szempont, ami eltér a QUIC és gQUIC között. Nincs értelme ezen sok időt tölteni, csak annyit mondanék, hogy a szabványosításra benyújtott verzióban a fejléc tömörítését maximálisan hasonlóvá tették a HTTP/2 fejléc tömörítéséhez. Részletesebben olvashat róla .
Mennyivel gyorsabb?
Ez egy bonyolult kérdés. A helyzet az, hogy mivel még nincs szabványunk, igazából nincs mit mérni. Talán az egyetlen statisztikai adat, amivel rendelkezünk, a Google statisztikája, amely a gQUIC-et 2013 óta használja, és 2016-ban , hogy a Chrome böngészőjéből érkező forgalom körülbelül 90%-a most már a QUIC-ot használja. Ugyanebben a bemutatóban azt is jelentik, hogy gQUIC-en keresztül az oldalak körülbelül 5%-kal gyorsabban töltődnek be, míg a streaming videók esetében 30%-kal kevesebb akadozást tapasztalunk a TCP-hez képest.
2017-ben egy Arash Molavi Kakhki vezette kutatócsoport közzétette a gQUIC teljesítményének vizsgálatáról a TCP-hez képest.
A kutatás számos gyengeséget tárt fel a gQUIC-ben, mint például a hálózati csomagok keveredésével szembeni érzékenység, a csatorna sávszélességével szembeni kapzsiság (unfairness) és a kis (10 kB-ig) objektumok lassú átvitele. Az utóbbi azonban 0-RTT használatával kompenzálható. Minden más vizsgált esetben a gQUIC sebességnövekedést mutatott a TCP-hez képest. A konkrét számokról itt nehéz beszélni. Jobb, ha elolvassa vagy .
Itt érdemes megemlíteni, hogy ezek az adatok kifejezetten a gQUIC-re vonatkoznak, és nem relevánsak a fejlesztés alatt álló szabványhoz. Mi vár a QUIC-re: ez még hét pecsétes titok, de reméljük, hogy a gQUIC-ben feltárt gyengeségek figyelembevételre és kijavításra kerülnek.
Egy kis jövőbelátás: mi a helyzet a HTTP/3-mal?
Itt minden kristálytiszta: az API semmiképpen sem változik. Minden úgy marad, ahogy volt az HTTP/2-ben. Ha az API változatlan marad, akkor a HTTP/3-ra való áttéréshez egy friss verziójú könyvtár használatával kell foglalkozni, amely támogatja a QUIC protokollt a háttérben. Igaz, még sokáig szükség lesz a régi HTTP verziókra való visszaesésre, mivel az internet még nincs felkészülve a teljes váltásra UDP-ra.
Ki már támogatja
Íme létező QUIC megvalósításokat. A szabvány hiánya ellenére a lista nem rossz.
Jelenleg egyetlen böngésző sem támogatja a QUIC-et éles verzióban. Nemrégiben információ érkezett, hogy a Chrome aktiválta a HTTP/3 támogatását, de egyelőre csak a Canary verzióban.
A háttértechnológiák közül a HTTP/3-at csak és , de egyelőre kísérleti módban. Az NGINX 2019 tavaszán , bejelentette, hogy dolgoznak a HTTP/3 támogatásán, de még nem fejezték be.
Milyen problémák vannak
Egy olyan világban élünk, ahol egyetlen nagy technológia sem juthat el a tömegekhez anélkül, hogy ellenállásba ne ütközne, és a QUIC sem kivétel.
A legfontosabb, hogy valahogy meg kell magyarázni a böngészőnek, hogy a "https://" most már nem biztos, hogy a 443-as TCP portra vezet. Ott akár TCP sincs. Ehhez az Alt-Svc fejlécet használjuk. Ez lehetővé teszi, hogy tájékoztassuk a böngészőt arról, hogy ez a weboldal egy másik protokollal elérhető egy adott címen. Elméletben ennek úgy kellene működnie, mint az óramű, de a gyakorlatban arra fogunk találkozni, hogy a UDP esetleg tiltva van a tűzfalon DDoS támadások elkerülése érdekében.
De még ha a UDP nincs is letiltva, az ügyfél NAT-router mögött lehet, amely a TCP kapcsolat fenntartására van beállítva az IP címen, és mivel UDP-t használunk, amelynek nincs hardveres kapcsolata, a NAT nem fogja fenntartani a kapcsolatot, így a QUIC kapcsolat .
Mindezek a problémák abból adódnak, hogy a UDP korábban nem lett használva internetes tartalom továbbítására, és a hardvergyártók nem tudták előre, hogy ez valaha megtörténik. Hasonlóképpen, az adminisztrátorok még nem igazán értik, hogyan állítsák be helyesen a hálózatokat a QUIC működésére. Ez a helyzet fokozatosan változni fog, és mindenesetre az ilyen változások kevesebb időt vesznek igénybe, mint egy új szállítási protokoll bevezetése.
Ezenkívül, ahogy korábban már említettük, a QUIC jelentősen megnöveli a processzor használatát. Daniel Stenberg a processzor növekedését akár háromszorosára.
Mikor érkezik el a HTTP/3
A szabványt 2020 májusáig, de figyelembe véve, hogy jelenleg az 2019 júliusára tervezett dokumentumok nincsenek befejezve, valószínűleg a dátumot el fogják tolni.
A Google pedig 2013 óta használja a saját gQUIC megvalósítását. Ha megnézzük a HTTP-kérést, amelyet a Google keresőmotorhoz küldenek, láthatjuk ezt:

Következtetések
A QUIC most egy meglehetősen nyers, de ígéretes technológia. Figyelembe véve, hogy az utolsó 20 évben a szállítási protokollok optimalizációja túlnyomórészt a TCP-re vonatkozott, a QUIC, amely a teljesítményben a legtöbb esetben előnyös, már most is rendkívül ígéretesnek tűnik.
Mindazonáltal még mindig megoldatlan problémák állnak előttünk, amelyekkel a következő néhány évben meg kell birkózni. A folyamat elhúzódhat, mivel a kérdéses hardver frissítése senkinek sem tetszik, de mindenesetre minden probléma teljesen megoldható, és előbb-utóbb mindannyiunknak lesz HTTP/3.
A jövő nem várathat magára!
Forrás: habr.com
