HTTP przez UDP – dobre wykorzystanie protokołu QUIC
QUIC (Quick UDP Internet Connections) to protokół będący uzupełnieniem protokołu UDP, który obsługuje wszystkie funkcje protokołów TCP, TLS i HTTP/2 i rozwiązuje większość ich problemów. Często nazywany jest protokołem nowym lub „eksperymentalnym”, ale już dawno przeżył fazę eksperymentalną: prace nad nim trwają ponad 7 lat. W tym czasie protokół nie stał się standardem, ale nadal stał się powszechny. Na przykład QUIC jest używany przez takich gigantów jak Google i Facebook do przyspieszania ruchu i zmniejszania opóźnień w sieciach komórkowych, a IETF ogłosił, że jego rozwidlenie protokołu stanowi podstawę standardu HTTP/3 (mimo że HTTP/2 wykorzystuje tylko 44.8% witryny).
Koncepcja
QUIC został opracowany jako zamiennik starszego protokołu TCP, który pierwotnie został zaprojektowany dla sieci przewodowych o niskich stratach. TCP dostarcza pakiety w kolejności, więc jeśli jeden pakiet zostanie utracony, cała kolejka zostanie zatrzymana (blokowanie czołówki), co negatywnie wpływa na jakość i stabilność połączenia. Aby uniknąć ogromnych strat, sieci komórkowe uciekają się do stosowania dużych buforów, co z kolei prowadzi do redundancji i fałszywie negatywnej odpowiedzi protokołu (rozdęcie buforu). Ponadto protokół TCP poświęca dużo czasu na ustanawianie połączenia: żądania SYN/ACK i TLS są przetwarzane oddzielnie, co wymaga trzech operacji w obie strony zamiast jednego, jak ma to miejsce w przypadku QUIC.
Ponieważ QUIC łączy w sobie zastąpienie protokołu TCP i implementację protokołu TLS 1.3, wszystkie połączenia są zawsze szyfrowane, a odszyfrowanie takiego ruchu nie jest łatwiejsze niż w przypadku przesyłania przez protokół HTTPS. Ponadto QUIC jest implementowany na poziomie aplikacji, ponieważ wymagałaby całkowitej wymiany stosu TCP wieczność.
Pomimo obsługi multipleksowania w HTTP/2, problem blokowania nagłówka linii pozostał niezmienny ze względu na konieczność dostarczania pakietów w odpowiedniej kolejności. QUIC jest zaimplementowany na bazie protokołu UDP, więc w zasadzie nie ma blokowania, a aby zapobiec trwałej utracie pakietów, są one numerowane i mogą zawierać części „sąsiadów”, zapewniając redundancję. Ponadto QUIC dzieli kolejkę monolityczną na wiele wątków dla różnych typów żądań w ramach jednego połączenia. Zatem w przypadku utraty pakietu mogą pojawić się problemy tylko w przypadku jednej kolejki (na przykład przy przesyłaniu określonego pliku):
Używać
Początkowo QUIC został opracowany w Google i był w dużej mierze dostosowany do użytku w firmie. W 2013 roku został przekazany do IETF w celu standaryzacji (która nadal trwa), a teraz każdy może uczestniczyć w rozwoju protokołu, proponując to, czego mu brakuje. Grupa robocza IETF organizuje coroczne spotkania, podczas których zatwierdzany jest nowy standard i omawiane są innowacje. Ta implementacja QUIC jest uważana za najważniejszą i to na jej podstawie certyfikowany jest standard HTTP/3.
Na razie nie ma mowy o włączeniu HTTP/3 jako głównego protokołu, ponieważ nie jest on jeszcze skończony i prawie nie jest wspierany:
Ale QUIC można zaimplementować jako transport między aplikacją a serwerem, co z sukcesem zostało zrobione w Uberze:
Komentarz Ubera na temat wprowadzenia QUIC
Aby pomyślnie osadzić QUIC i poprawić wydajność aplikacji w środowiskach o słabej łączności, zastąpiliśmy stary stos (HTTP/2 przez TLS/TCP) protokołem QUIC. Korzystaliśmy z biblioteki sieciowej Cronet z Projekty Chromowe, który zawiera oryginalną, Google wersję protokołu - gQUIC. Ta implementacja jest również stale udoskonalana, aby była zgodna z najnowszą specyfikacją IETF.
Najpierw zintegrowaliśmy Cronet z naszymi aplikacjami na Androida, aby dodać obsługę QUIC. Integracja została przeprowadzona w taki sposób, aby w jak największym stopniu obniżyć koszty migracji. Zamiast całkowicie zastąpić stary stos sieciowy, który korzystał z biblioteki OkHttp, zintegrowaliśmy Cronet W RAMACH frameworku OkHttp API. Wykonując integrację w ten sposób, uniknęliśmy zmian w naszych połączeniach sieciowych (z których korzystają Modernizacja) na poziomie API.
Podobnie jak w przypadku urządzeń z systemem Android, zaimplementowaliśmy Cronet w aplikacjach Ubera na iOS, przechwytując ruch HTTP z sieci APIKorzystanie Protokół NSURL. Ta abstrakcja, dostarczona przez iOS Foundation, obsługuje dane URL specyficzne dla protokołu i zapewnia, że możemy zintegrować Cronet z naszymi aplikacjami iOS bez znacznych kosztów migracji.
Na backendzie przechwycili połączenia QUIC za pośrednictwem Google Cloud lb, które obsługuje protokół od połowy 2018 roku.
Nic dziwnego, że Google Cloud świetnie współpracuje z protokołem opracowanym przez Google, ale jakie są alternatywy?
nginx
Nie tak dawno temu CloudFlare Próbowałem przejść nginx (który domyślnie nie obsługuje protokołu HTTP/3) za pomocą narzędzia Quiche. Implementacja jest dostępna w postaci pojedynczego pliku .patch, do którego dołączony jest samouczek instalacji:
curl -O https://nginx.org/download/nginx-1.16.1.tar.gz
tar xvzf nginx-1.16.1.tar.gz
git clone --recursive https://github.com/cloudflare/quiche
cd nginx-1.16.1
patch -p01 < ../quiche/extras/nginx/nginx-1.16.patch
W razie potrzeby możesz tutaj podłączyć swoje moduły
./configure
--prefix=$PWD
--with-http_ssl_module
--with-http_v2_module
--with-http_v3_module
--with-openssl=../quiche/deps/boringssl
--with-quiche=../quiche
make
Pozostaje tylko włączyć obsługę protokołu HTTP/3
events {
worker_connections 1024;
}
http {
server {
# Enable QUIC and HTTP/3.
listen 443 quic reuseport;
# Enable HTTP/2 (optional).
listen 443 ssl http2;
ssl_certificate cert.crt;
ssl_certificate_key cert.key;
# Enable all TLS versions (TLSv1.3 is required for QUIC).
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
# Request buffering in not currently supported for HTTP/3.
proxy_request_buffering off;
# Add Alt-Svc header to negotiate HTTP/3.
add_header alt-svc 'h3-27=":443"; ma=86400';
}
}
Nie jest jeszcze możliwe połączenie przez HTTP/3 w zwykłych przeglądarkach, ale można z tego skorzystać Chrome Canary i uruchom go z flagą --enable-quic, przejdź do swojego serwera lub na przykład witryny quic.rocks i sprawdź typ połączenia w Narzędziach dla programistów:
Zamiast HTTP/3 jest napisany http2+quic/99, ale w zasadzie to to samo.
Inne technologie
QUIC również obsługuje LiteSpeed (który łączył się z Facebookiem poprzez HTTP/3 z wielkimi pompami) i progresywny Nosiciel kijów golfowych. Apache jeszcze tego nie potrafi, ale prace trwają Pełną parą.
Któregoś dnia Microsoft otworzył swoją działalność kod implementacyjny msquic, w którym nie wszystkie funkcje ze standardu IETF są jeszcze dostępne, ale to już duży przełom.
wniosek
Zainteresowanie QUIC jest niestabilne, ale rośnie i trwają prace nad jego standaryzacją. Nowe wdrożenia protokołu pojawiają się niemal co miesiąc i z roku na rok coraz więcej programistów jest przekonanych, że QUIC to przyszłość. Możliwe jest nawet włączenie protokołu w przyszłych wersjach stosu TCP, co oznacza, że prędzej czy później cały Internet przejdzie na stabilniejsze i szybsze połączenia.
Już teraz możesz skonfigurować interakcję QUIC dla swojej infrastruktury, a nawet dać ją przeglądarkom - wszystkie planują dodać obsługę protokołu, a smutne statystyki z caniuse staną się pogodniejsze.