HTTP/3: Breaking the Ground e Brave New World

Da più di 20 anni visualizziamo le pagine web utilizzando il protocollo HTTP. La maggior parte degli utenti non pensa nemmeno a cosa sia e come funzioni. Altri sanno che da qualche parte sotto HTTP c'è TLS, e sotto c'è TCP, sotto il quale c'è IP e così via. Altri ancora, gli eretici, credono che TCP sia una cosa del passato e vogliono qualcosa di più veloce, più affidabile e sicuro. Ma nel tentativo di inventare un nuovo protocollo ideale, sono tornati alla tecnologia degli anni ’80 e stanno cercando di costruire su di essa il loro nuovo mondo.
HTTP/3: Breaking the Ground e Brave New World

Un po' di storia: HTTP/1.1

Nel 1997, il protocollo di scambio di informazioni testuali HTTP versione 1.1 ha acquisito il proprio RFC. A quel tempo, il protocollo era utilizzato dai browser già da diversi anni e il nuovo standard durò altri quindici. Il protocollo funzionava solo secondo il principio richiesta-risposta ed era destinato principalmente alla trasmissione di informazioni testuali.

HTTP è stato progettato per funzionare sul protocollo TCP, garantendo che i pacchetti vengano consegnati in modo affidabile alla loro destinazione. TCP funziona stabilendo e mantenendo una connessione affidabile tra gli endpoint e suddividendo il traffico in segmenti. I segmenti hanno il proprio numero di serie e checksum. Se improvvisamente uno dei segmenti non arriva o arriva con un checksum errato, la trasmissione si interromperà fino al ripristino del segmento perduto.

In HTTP/1.0, la connessione TCP veniva chiusa dopo ogni richiesta. Questo è stato estremamente dispendioso, perché... stabilire una connessione TCP (3-Way-Handshake) è un processo lento. HTTP/1.1 ha introdotto il meccanismo keep-alive, che consente di riutilizzare una connessione per più richieste. Tuttavia, poiché può facilmente diventare un collo di bottiglia, varie implementazioni di HTTP/1.1 consentono di aprire più connessioni TCP verso lo stesso host. Ad esempio, Chrome e le versioni recenti di Firefox consentono fino a sei connessioni.
HTTP/3: Breaking the Ground e Brave New World
Anche la crittografia avrebbe dovuto essere lasciata ad altri protocolli e per questo è stato utilizzato il protocollo TLS su TCP, che proteggeva in modo affidabile i dati, ma aumentava ulteriormente il tempo necessario per stabilire una connessione. Di conseguenza, il processo di stretta di mano ha iniziato ad assomigliare a questo:
HTTP/3: Breaking the Ground e Brave New World
Illustrazione di Cloudflare

Pertanto HTTP/1.1 presentava una serie di problemi:

  • Configurazione della connessione lenta.
  • I dati vengono trasmessi in forma testuale, pertanto la trasmissione di immagini, video e altre informazioni non testuali è inefficace.
  • Per una richiesta viene utilizzata una connessione TCP, il che significa che le altre richieste devono trovare un'altra connessione o attendere finché la richiesta corrente non la rilascia.
  • È supportato solo il modello pull. Non c'è nulla nello standard riguardo al server-push.
  • I titoli vengono trasmessi sotto forma di testo.

Se il server push venisse almeno implementato utilizzando il protocollo WebSocket, i problemi rimanenti dovrebbero essere affrontati in modo più radicale.

Un po' di modernità: HTTP/2

Nel 2012, Google ha iniziato a lavorare sul protocollo SPDY (pronunciato “speedy”). Il protocollo è stato progettato per risolvere i principali problemi di HTTP/1.1 e allo stesso tempo avrebbe dovuto mantenere la compatibilità con le versioni precedenti. Nel 2015 il gruppo di lavoro IETF ha introdotto la specifica HTTP/2 basata sul protocollo SPDY. Ecco le differenze in HTTP/2:

  • Serializzazione binaria.
  • Multiplexing di più richieste HTTP in un'unica connessione TCP.
  • Server-push out of the box (senza WebSocket).

Il protocollo è stato un grande passo avanti. Lui fortemente batte la prima versione in velocità e non richiede la creazione di connessioni TCP multiple: tutte le richieste a un host vengono multiplexate in una sola. Cioè, in una connessione ci sono diversi cosiddetti flussi, ognuno dei quali ha il proprio ID. Il bonus è un push del server in scatola.

Tuttavia, il multiplexing porta ad un altro problema chiave. Immagina di eseguire in modo asincrono 5 richieste su un server. Quando si utilizza HTTP/2, tutte queste richieste verranno eseguite all'interno della stessa connessione TCP, il che significa che se uno dei segmenti di una qualsiasi richiesta viene perso o ricevuto in modo errato, la trasmissione di tutte le richieste e risposte si interromperà finché il segmento perso non sarà restaurato. Ovviamente, peggiore è la qualità della connessione, più lento sarà il funzionamento di HTTP/2. Secondo Daniel Stenberg, in condizioni in cui i pacchetti persi rappresentano il 2% di tutti i pacchetti, HTTP/1.1 nel browser funziona meglio di HTTP/2 perché apre 6 connessioni anziché una.

Questo problema è chiamato “blocco head-of-line” e, sfortunatamente, non è possibile risolverlo quando si utilizza TCP.
HTTP/3: Breaking the Ground e Brave New World
Illustrazione di Daniel Steinberg

Di conseguenza, gli sviluppatori dello standard HTTP/2 hanno fatto un ottimo lavoro e hanno fatto quasi tutto ciò che si poteva fare a livello di applicazione del modello OSI. È ora di scendere al livello di trasporto e inventare un nuovo protocollo di trasporto.

Abbiamo bisogno di un nuovo protocollo: UDP vs TCP

È diventato subito chiaro che implementare un protocollo del livello di trasporto completamente nuovo è un compito impossibile nella realtà odierna. Il fatto è che l'hardware o i middle-box (router, firewall, server NAT...) conoscono il livello di trasporto e insegnare loro qualcosa di nuovo è un compito estremamente difficile. Inoltre, il supporto per i protocolli di trasporto è integrato nel kernel dei sistemi operativi e anche i kernel non sono molto disposti a cambiare.

E qui si potrebbe alzare le mani e dire “Noi, ovviamente, inventeremo un nuovo HTTP/3 con preferenze e cortigiane, ma ci vorranno 10-15 anni per essere implementato (dopo circa questo tempo la maggior parte dell'hardware sarà sostituito)", ma ce n'è un altro che non è così. L'opzione ovvia è utilizzare il protocollo UDP. Sì, sì, lo stesso protocollo che usavamo per trasferire file sulla LAN alla fine degli anni Novanta e all'inizio degli anni XNUMX. Quasi tutto l'hardware odierno può funzionare con esso.

Quali sono i vantaggi di UDP rispetto a TCP? Prima di tutto, non abbiamo una sessione del livello di trasporto di cui l’hardware è a conoscenza. Ciò ci consente di determinare noi stessi la sessione sugli endpoint e di risolvere i conflitti lì. Cioè, non siamo limitati a una o più sessioni (come in TCP), ma possiamo crearne quante ne abbiamo bisogno. In secondo luogo, la trasmissione dei dati tramite UDP è più veloce che tramite TCP. Quindi, in teoria, possiamo superare l’attuale limite di velocità raggiunto in HTTP/2.

Tuttavia, UDP non garantisce una trasmissione dati affidabile. In effetti, stiamo semplicemente inviando pacchetti, sperando che l'altra estremità li riceva. Non hanno ricevuto? Beh, niente... Questo è bastato per trasmettere video per adulti, ma per cose più serie ci vuole affidabilità, il che significa che devi aggiungere qualcos'altro oltre a UDP.

Come per HTTP/2, il lavoro sulla creazione di un nuovo protocollo è iniziato in Google nel 2012, cioè più o meno nello stesso periodo in cui è iniziato il lavoro su SPDY. Nel 2013, Jim Roskind ha presentato al grande pubblico Protocollo QUIC (Connessioni Internet Quick UDP)., e già nel 2015 è stato introdotto l'Internet Draft per la standardizzazione nell'IETF. Già a quel tempo il protocollo sviluppato da Roskind presso Google era molto diverso dallo standard, quindi la versione di Google cominciò a chiamarsi gQUIC.

Cos'è QUIC

Innanzitutto, come già accennato, si tratta di un wrapper su UDP. Sopra UDP si sviluppa una connessione QUIC nella quale, per analogia con HTTP/2, possono esistere più flussi. Questi flussi esistono solo sugli endpoint e vengono serviti in modo indipendente. Se si verifica una perdita di pacchetti in un flusso, ciò non influirà sugli altri.
HTTP/3: Breaking the Ground e Brave New World
Illustrazione di Daniel Steinberg

In secondo luogo, la crittografia non viene più implementata a un livello separato, ma è inclusa nel protocollo. Ciò consente di stabilire una connessione e scambiare chiavi pubbliche in un unico handshake e consente inoltre di utilizzare l'intelligente meccanismo di handshake 0-RTT ed evitare del tutto i ritardi di handshake. Inoltre ora è possibile crittografare singoli pacchetti di dati. Ciò consente di non attendere il completamento della ricezione dei dati dal flusso, ma di decrittografare autonomamente i pacchetti ricevuti. Questa modalità operativa era generalmente impossibile in TCP, perché TLS e TCP funzionavano indipendentemente l'uno dall'altro e TLS non poteva sapere in quali pezzi i dati TCP sarebbero stati suddivisi. Pertanto, non poteva preparare i suoi segmenti in modo che si adattassero uno a uno ai segmenti TCP e potessero essere decifrati in modo indipendente. Tutti questi miglioramenti consentono a QUIC di ridurre la latenza rispetto a TCP.
HTTP/3: Breaking the Ground e Brave New World
In terzo luogo, il concetto di light streaming consente di disaccoppiare la connessione dall’indirizzo IP del client. Questo è importante, ad esempio, quando un client passa da un punto di accesso Wi-Fi a un altro, cambiando il suo IP. In questo caso, quando si utilizza TCP, si verifica un lungo processo durante il quale le connessioni TCP esistenti scadono e vengono create nuove connessioni da un nuovo IP. Nel caso di QUIC, il client continua semplicemente a inviare pacchetti al server da un nuovo IP con il vecchio ID di flusso. Perché L'ID del flusso è ora univoco e non viene riutilizzato; il server capisce che il client ha cambiato IP, invia nuovamente i pacchetti persi e continua la comunicazione al nuovo indirizzo.

In quarto luogo, QUIC è implementato a livello di applicazione, non a livello di sistema operativo. Questo, da un lato, ti consente di apportare rapidamente modifiche al protocollo, perché Per ottenere un aggiornamento, devi solo aggiornare la libreria, anziché attendere una nuova versione del sistema operativo. D'altro canto, questo porta ad un forte aumento del consumo del processore.

E infine i titoli. La compressione dell'intestazione è una delle cose che differiscono tra QUIC e gQUIC. Non vedo il motivo di dedicare molto tempo a questo, dirò solo che nella versione inviata per la standardizzazione, la compressione dell'intestazione è stata resa il più simile possibile alla compressione dell'intestazione in HTTP/2. Puoi leggere di più qui.

Quanto è più veloce?

È una domanda difficile. Il fatto è che finché non avremo uno standard, non c’è nulla di speciale da misurare. Forse le uniche statistiche che abbiamo sono quelle di Google, che utilizza gQUIC dal 2013 e nel 2016 segnalato all'IETFche circa il 90% del traffico diretto ai loro server dal browser Chrome ora utilizza QUIC. Nella stessa presentazione, riferiscono che le pagine si caricano circa il 5% più velocemente tramite gQUIC e ci sono il 30% in meno di scatti nello streaming video rispetto a TCP.

Nel 2017, un gruppo di ricercatori guidati da Arash Molavi Kakhki ha pubblicato ottimo lavoro studiare le prestazioni di gQUIC rispetto a TCP.
Lo studio ha rivelato diversi punti deboli di gQUIC, come l'instabilità nel mescolare i pacchetti di rete, l'avidità (ingiustizia) nel canalizzare la larghezza di banda e il trasferimento più lento di oggetti piccoli (fino a 10 kb). Quest'ultimo, tuttavia, può essere compensato utilizzando 0-RTT. In tutti gli altri casi studiati, gQUIC ha mostrato un aumento della velocità rispetto a TCP. È difficile parlare di numeri specifici qui. Meglio leggere lo studio stesso o breve post.

Va detto che questi dati riguardano specificamente gQUIC e non sono rilevanti per lo standard in fase di sviluppo. Cosa accadrà a QUIC: è ancora un segreto, ma c’è la speranza che i punti deboli individuati in gQUIC vengano presi in considerazione e corretti.

Un po' di futuro: che dire di HTTP/3?

Ma qui tutto è chiarissimo: l'API non cambierà in alcun modo. Tutto rimarrà esattamente uguale a come era in HTTP/2. Bene, se l’API rimane la stessa, la transizione a HTTP/3 dovrà essere risolta utilizzando una nuova versione della libreria sul backend che supporti il ​​trasporto QUIC. È vero, dovrai mantenere il fallback sulle vecchie versioni di HTTP per un bel po' di tempo, perché Internet attualmente non è pronta per una transizione completa all'UDP.

Chi già sostiene

Qui elenco implementazioni QUIC esistenti. Nonostante la mancanza di uno standard, l’elenco non è male.

Nessun browser attualmente supporta QUIC in una versione di produzione. Recentemente sono emerse informazioni secondo cui il supporto per HTTP/3 era incluso in Chrome, ma finora solo in Canary.

Tra i backend, supporta solo HTTP/3 Portabastoni и Cloudflare, ma ancora sperimentale. NGINX alla fine della primavera 2019 annunciato, che hanno iniziato a lavorare sul supporto HTTP/3, ma non l'hanno ancora finito.

Quali sono i problemi?

Tu ed io viviamo nel mondo reale, dove nessuna grande tecnologia può raggiungere le masse senza incontrare resistenza, e QUIC non fa eccezione.

La cosa più importante è che devi in ​​qualche modo spiegare al browser che "https://" non è più un dato di fatto che porta alla porta TCP 443. Potrebbe non esserci affatto TCP. A questo scopo viene utilizzata l'intestazione Alt-Svc. Ti consente di dire al browser che questo sito web è disponibile anche su questo o quel protocollo a questo e quell'indirizzo. In teoria dovrebbe funzionare come un incantesimo, ma in pratica ci imbattiamo nel fatto che UDP può, ad esempio, essere proibito su un firewall per evitare attacchi DDoS.

Ma anche se l'UDP non è proibito, il client potrebbe trovarsi dietro un router NAT configurato per tenere una sessione TCP tramite indirizzo IP e poiché utilizziamo UDP, che non ha una sessione hardware, NAT non manterrà la connessione e una sessione QUIC si interromperà costantemente.

Tutti questi problemi sono dovuti al fatto che UDP non era mai stato utilizzato prima per trasmettere contenuti Internet e i produttori di hardware non potevano prevedere che ciò sarebbe mai accaduto. Allo stesso modo, gli amministratori non capiscono ancora veramente come configurare correttamente le loro reti affinché QUIC funzioni. Questa situazione cambierà gradualmente e, in ogni caso, tali cambiamenti richiederanno meno tempo dell’implementazione di un nuovo protocollo del livello di trasporto.

Inoltre, come già descritto, QUIC aumenta notevolmente l'utilizzo della CPU. Daniele Stenberg ho apprezzato crescita del processore fino a tre volte.

Quando arriverà HTTP/3?

Standard vuole accettare entro maggio 2020, ma dato che i documenti previsti per luglio 2019 restano al momento incompiuti, possiamo dire che molto probabilmente la data verrà posticipata.

Ebbene, Google utilizza la sua implementazione gQUIC dal 2013. Se guardi la richiesta HTTP che viene inviata al motore di ricerca di Google, vedrai questo:
HTTP/3: Breaking the Ground e Brave New World

risultati

QUIC ora sembra una tecnologia piuttosto rozza, ma molto promettente. Considerando che negli ultimi 20 anni tutte le ottimizzazioni dei protocolli del livello di trasporto hanno riguardato principalmente TCP, QUIC, che nella maggior parte dei casi ha le prestazioni migliori, sembra già estremamente buono.

Rimangono però ancora problemi irrisolti che dovranno essere affrontati nei prossimi anni. Il processo può essere ritardato a causa del fatto che è coinvolto dell'hardware che a nessuno piace aggiornare, ma nonostante ciò tutti i problemi sembrano abbastanza risolvibili e prima o poi avremo tutti HTTP/3.

Il futuro è proprio dietro l’angolo!

Fonte: habr.com

Aggiungi un commento