HTTP / 3: quebrando as fundações e um admirável mundo novo

Há mais de 20 anos, visualizamos páginas da Web usando o protocolo HTTP. A maioria dos usuários não pensa sobre o que é e como funciona. Outros sabem que em algum lugar sob HTTP existe TLS e, sob ele, TCP, sob qual IP e assim por diante. E o terceiro - hereges - acredita que o TCP é o século passado, eles querem algo mais rápido, mais confiável e mais seguro. Mas, em suas tentativas de inventar um novo protocolo ideal, eles voltaram às tecnologias dos anos 80 e estão tentando construir sobre eles o seu admirável mundo novo.


Um pouco de história: HTTP / 1.1


Em 1997, o protocolo de troca de texto HTTP versão 1.1 ganhou seu RFC. Naquela época, o protocolo era usado pelos navegadores por vários anos, e o novo padrão durava outros quinze. O protocolo funcionava apenas com base na solicitação-resposta e era destinado principalmente à transmissão de informações textuais.

O HTTP foi projetado para funcionar com base no protocolo TCP, que garante a entrega confiável de pacotes ao destino. O TCP baseia-se no estabelecimento e na manutenção de uma conexão confiável entre os terminais e o tráfego de segmentação. Os segmentos têm seu próprio número de sequência e soma de verificação. Se de repente um dos segmentos não vier ou vier com a soma de verificação errada, a transmissão será interrompida até que o segmento perdido seja restaurado.

No HTTP / 1.0, a conexão TCP foi fechada após cada solicitação. Foi extremamente inútil, já que Estabelecer uma conexão TCP (Handshake de 3 vias) não é um processo rápido. O HTTP / 1.1 introduziu o mecanismo keep-alive, que permite reutilizar uma única conexão para várias solicitações. No entanto, como ele pode facilmente se tornar um gargalo, várias conexões TCP / IP com o mesmo host são permitidas em diferentes implementações HTTP / 1.1. Por exemplo, no Chrome e nas versões recentes do Firefox, são permitidas até seis conexões.

A criptografia também deveria ser deixada para outros protocolos e, para isso, o protocolo TLS era usado sobre TCP, que protegia dados com segurança, mas aumentava ainda mais o tempo necessário para estabelecer uma conexão. Como resultado, o processo de handshake começou a ficar assim:

Ilustração Cloudflare

Assim, o HTTP / 1.1 teve vários problemas:

  • Configuração de conexão lenta.
  • Uma conexão TCP é usada para uma solicitação, o que significa que o restante das solicitações deve encontrar outra conexão ou aguardar até que a solicitação atual a libere.
  • Apenas o modelo pull é suportado. Não há nada no padrão sobre push do servidor.
  • Os títulos são transmitidos em texto.

Se o push do servidor for implementado de alguma forma usando o protocolo WebSocket, o restante dos problemas precisará ser tratado de maneira mais radical.

Um pouco de modernidade: HTTP / 2


Em 2012, o trabalho no protocolo SPDY (pronunciado “velocidade”) começou nas entranhas do Google. O protocolo foi projetado para resolver os problemas básicos do HTTP / 1.1 e, ao mesmo tempo, precisava manter a compatibilidade com versões anteriores. Em 2015, o grupo de trabalho da IETF introduziu a especificação HTTP / 2 com base no protocolo SPDY. Aqui estão as diferenças no HTTP / 2:

  • Serialização binária.
  • Multiplexar várias solicitações HTTP em uma única conexão TCP.
  • Push do servidor pronto para uso (sem WebSocket).

O protocolo foi um grande passo em frente. Ele supera muito a primeira versão e não requer a criação de várias conexões TCP: todos os pedidos para um host são multiplexados em um. Ou seja, em uma conexão, existem vários fluxos chamados, cada um com seu próprio ID. O bônus é um push do servidor in a box.

No entanto, a multiplicação leva a outro problema fundamental. Imagine que executamos assincronamente 5 solicitações para um servidor. Ao usar HTTP / 2, todas essas solicitações serão executadas na mesma conexão TCP, o que significa que, se um dos segmentos de qualquer solicitação for perdido ou chegar incorretamente, a transmissão de todas as solicitações e respostas será interrompida até que o segmento perdido seja restaurado. Obviamente, quanto pior a qualidade da conexão, mais lento o HTTP / 2 funciona. De acordo com Daniel Stenberg , em uma situação em que os pacotes perdidos representam 2% de todos, o HTTP / 1.1 em um navegador tem um desempenho melhor que o HTTP / 2 devido ao fato de abrir 6 conexões, não uma.

Esse problema é chamado de "bloqueio de linha de frente" e, infelizmente, não é possível resolvê-lo usando o TCP.

Ilustração de Daniel Steinberg

Como resultado, os desenvolvedores do padrão HTTP / 2 fizeram um ótimo trabalho e fizeram quase tudo o que podia ser feito no nível do aplicativo do modelo OSI. É hora de descer ao nível de transporte e inventar um novo protocolo de transporte.

Precisamos de um novo protocolo: UDP vs TCP


Muito rapidamente ficou claro que introduzir um protocolo de camada de transporte completamente novo é uma tarefa insolúvel nas realidades de hoje. O fato é que as glândulas ou caixas intermediárias (roteadores, firewalls, servidores NAT ...) conhecem o nível de transporte e ensinar algo novo a elas é uma tarefa extremamente difícil. Além disso, o suporte a protocolos de transporte está conectado ao kernel dos sistemas operacionais, e os kernels também mudam de maneira não muito voluntária.

E aqui pode-se desistir e dizer: "É claro que inventaremos um novo HTTP / 3 com preferência e cortesãs, mas será implementado em 10 a 15 anos (após esse período, a maioria das glândulas será substituída)", mas há mais uma opção óbvia: use o protocolo UDP. Sim, sim, o mesmo protocolo de acordo com o qual lançamos arquivos em uma LAN no final dos anos 90 e no início de zero. Quase todas as peças de ferro de hoje sabem como trabalhar com ela.

Quais são as vantagens do UDP sobre TCP? Primeiro de tudo, não temos uma sessão de nível de transporte que a Iron conheça. Isso nos permite determinar a sessão nos pontos de extremidade e resolver conflitos que surgem lá. Ou seja, não estamos limitados a uma ou várias sessões (como no TCP), mas podemos criá-las o quanto for necessário. Em segundo lugar, a transmissão de dados pelo UDP é mais rápida que pelo TCP. Assim, em teoria, podemos romper o limite de velocidade de hoje alcançado em HTTP / 2.

No entanto, o UDP não garante transmissão de dados confiável. De fato, simplesmente enviamos pacotes, esperando que sejam recebidos no outro extremo. Não recebeu? Bem, sem sorte ... Isso foi o suficiente para transmitir vídeo para adultos, mas para coisas mais sérias você precisa de confiabilidade, o que significa que você precisa enrolar algo mais sobre o UDP.

Assim como no HTTP / 2, o trabalho de criação de um novo protocolo começou no Google em 2012, ou seja, quase ao mesmo tempo que o início do trabalho no SPDY. Em 2013, Jim Roskind introduziu o protocolo QUIC (Quick UDP Internet Connections) ao público em geral e, em 2015, o Internet Draft foi introduzido para padronizar o IETF. Já naquela época, o protocolo desenvolvido por Roskind no Google era muito diferente do padrão, então a versão do Google era chamada gQUIC.

O que é QUIC


Primeiro, como já mencionado, este é um invólucro sobre o UDP. A conexão QUIC se eleva acima do UDP, na qual, por analogia com HTTP / 2, vários fluxos podem existir. Esses fluxos existem apenas nos pontos de extremidade e são atendidos independentemente. Se a perda de pacotes ocorreu em um fluxo, isso não afetará os outros.

Ilustração de Daniel Steinberg

Em segundo lugar, a criptografia agora é implementada não em um nível separado, mas incluída no protocolo. Isso permite que você estabeleça uma conexão e troque chaves públicas em um único handshake, além de usar o complicado mecanismo de handshake 0-RTT e geralmente evite atrasos nas mãos trêmulas. Além disso, pacotes de dados individuais agora podem ser criptografados. Isso permite que você não espere pela conclusão do recebimento de dados do fluxo, mas descriptografe os pacotes recebidos independentemente. Este modo de operação não era possível no TCP, porque O TLS e o TCP funcionavam independentemente um do outro, e o TLS não sabia em que partes os dados do TCP seriam divididos. E, portanto, não pude preparar meus segmentos para que eles se ajustassem aos segmentos TCP um a um e pudessem ser descriptografados independentemente. Todas essas melhorias permitem que o QUIC reduza a latência em comparação com o TCP.

Em terceiro lugar, o conceito de fluxos fáceis permite desatar a conexão do endereço IP do cliente. Isso é importante, por exemplo, quando um cliente muda de um ponto de acesso Wi-Fi para outro, alterando seu IP. Nesse caso, ao usar o TCP, ocorre um longo processo durante o qual as conexões TCP existentes caem no tempo limite e novas conexões são criadas a partir do novo IP. No caso do QUIC, o cliente simplesmente continua a enviar pacotes do novo IP para o servidor com o ID do fluxo antigo. Porque O ID do fluxo agora é exclusivo e não é reutilizado, o servidor entende que o cliente alterou o IP, envia os pacotes perdidos e continua a comunicação com o novo endereço.

Quarto, o QUIC é implementado no nível do aplicativo, não no sistema operacional. Isso, por um lado, permite mudanças mais rápidas no protocolo, como Para obter uma atualização, basta atualizar a biblioteca, em vez de esperar por uma nova versão do sistema operacional. Por outro lado, isso leva a um forte aumento no consumo do processador.

E, finalmente, as manchetes. A compactação de cabeçalho refere-se apenas a pontos que diferem em QUIC e gQUIC. Não vejo razão para dedicar muito tempo a isso; só posso dizer que na versão enviada para padronização, a compactação de cabeçalho foi feita o mais semelhante possível à compactação de cabeçalho no HTTP / 2. Mais detalhes podem ser lidos aqui .

Quão rápido é?


Esta é uma pergunta complicada. O fato é que, embora não tenhamos um padrão, não há nada especial para medir. Talvez as únicas estatísticas que temos sejam as estatísticas do Google, que usam o gQUIC desde 2013 e em 2016 relataram à IETF que cerca de 90% do tráfego que chega aos seus servidores no navegador Chrome agora está usando o QUIC. Na mesma apresentação, eles relatam que, por meio do gQUIC, as páginas carregam cerca de 5% mais rápido e o streaming de vídeo tem 30% menos congelamentos em comparação com o TCP.

Em 2017, um grupo de pesquisadores liderado por Arash Molavi Kakhki publicou um grande trabalho sobre o estudo do desempenho do gQUIC comparado ao TCP.
O estudo revelou vários pontos fracos do gQUIC, como instabilidade na mistura de pacotes de rede, injustiça na capacidade do canal e transferência mais lenta de objetos pequenos (até 10 kb). Este último, no entanto, pode ser compensado pelo uso do 0-RTT. Em todos os outros casos investigados, o gQUIC mostrou um aumento na velocidade em comparação ao TCP. É difícil falar sobre números específicos. É melhor ler o estudo em si ou um post curto .

Aqui, deve-se dizer que esses dados são especificamente sobre gQUIC e são irrelevantes para o padrão que está sendo desenvolvido. O que acontecerá com o QUIC: até agora, o mistério está por trás de sete selos, mas há esperança de que as fraquezas identificadas pelo gQUIC sejam levadas em consideração e corrigidas.

Um pouco de futuro: e o HTTP / 3?


E aqui está tudo claro: a API não muda de forma alguma. Tudo permanecerá exatamente igual ao HTTP / 2. Bem, se a API permanecer a mesma, a transição para o HTTP / 3 terá que ser decidida usando a versão mais recente da biblioteca que suporta o transporte via QUIC no back-end. É verdade que, por um longo tempo, você ainda precisa manter o fallback para versões mais antigas do HTTP, porque a Internet não está pronta para uma mudança completa para o UDP.

Quem já está apoiando


Aqui está uma lista de implementações QUIC existentes. Apesar da falta de um padrão, a lista não é ruim.

Atualmente, nenhum navegador suporta QUIC na versão. Recentemente, havia informações de que o Chrome incluía suporte a HTTP / 3, mas até agora apenas no Canary.

Dos back-ends, o HTTP / 3 suporta apenas Caddy e Cloudflare , mas até agora experimentalmente. A NGINX anunciou no final da primavera de 2019 que havia começado a trabalhar no suporte a HTTP / 3, mas ainda não o havia concluído.

Quais são os problemas


Vivemos no mundo real, onde nem uma única grande tecnologia pode chegar às massas sem encontrar resistência, e o QUIC não é exceção.

Mais importante, você precisa de alguma forma explicar ao navegador que "https: //" não é mais um fato que leva à 443ª porta TCP. Pode não haver TCP. Para fazer isso, use o cabeçalho Alt-Svc. Ele permite que o navegador seja informado de que este site também está disponível em tal protocolo e em tal endereço. Em teoria, isso deve funcionar como um relógio, mas, na prática, nos deparamos com o fato de que o UDP pode ser, por exemplo, desativado em um firewall para evitar ataques DDoS.

Mas, mesmo que o UDP não seja proibido, o cliente pode estar atrás de um roteador NAT configurado para armazenar uma sessão TCP por endereço IP, como usamos o UDP, em que não há sessão de hardware, o NAT não retém a conexão e a sessão QUIC sempre é encerrada .

Todos esses problemas estão relacionados ao fato de o UDP não ter sido usado anteriormente para transmitir conteúdo da Internet e os fabricantes de hardware não poderiam prever que isso aconteceria. Da mesma forma, os administradores ainda não entendem como configurar corretamente suas redes para o QUIC. Essa situação mudará lentamente e, em qualquer caso, essas alterações levarão menos tempo do que a introdução de um novo protocolo da camada de transporte.

Além disso, como já descrito, o QUIC aumenta bastante a utilização do processador. Daniel Stenberg avaliou o crescimento do processador em até três vezes.

Quando o HTTP / 3 chega


Eles querem adotar o padrão até maio de 2020, mas, como os documentos agendados para julho de 2019 permanecem inacabados, podemos dizer que a data provavelmente será adiada.

Bem, o Google usa sua implementação do gQUIC desde 2013. Se você olhar para a solicitação HTTP enviada ao mecanismo de pesquisa do Google, poderá ver o seguinte:


Conclusões


O QUIC agora parece uma tecnologia bastante bruta, mas muito promissora. Considerando que, nos últimos 20 anos, todas as otimizações dos protocolos da camada de transporte relacionadas principalmente ao TCP, QUIC, que na maioria dos casos obtém desempenho, agora parecem extremamente boas.

No entanto, ainda existem problemas não resolvidos que devem ser tratados nos próximos anos. O processo pode ser atrasado devido ao fato de haver hardware envolvido, que ninguém gosta de atualizar, mas, no entanto, todos os problemas parecem bastante solucionáveis ​​e, mais cedo ou mais tarde, todos teremos HTTP / 3.

O futuro não está longe!

Source: https://habr.com/ru/post/pt473930/


All Articles