Co oznacza multipleksowanie w HTTP / 2

Odpowiedzi:

221

Mówiąc prościej, multipleksowanie pozwala przeglądarce na odpalenie wielu żądań jednocześnie na tym samym połączeniu i otrzymywanie żądań z powrotem w dowolnej kolejności.

A teraz o wiele bardziej skomplikowana odpowiedź ...

Kiedy ładujesz stronę internetową, pobiera ją HTML, widzi, że potrzebuje trochę CSS, trochę JavaScript, ładunek obrazów ... itd.

W ramach protokołu HTTP / 1.1 możesz pobrać tylko jedną z nich na raz w połączeniu HTTP / 1.1. Twoja przeglądarka pobiera więc HTML, a następnie prosi o plik CSS. Po zwróceniu prosi o plik JavaScript. Kiedy jest zwracany, prosi o pierwszy plik obrazu ... itd. HTTP / 1.1 jest zasadniczo synchroniczny - po wysłaniu żądania utkniesz, dopóki nie otrzymasz odpowiedzi. Oznacza to, że przez większość czasu przeglądarka nie robi zbyt wiele, ponieważ odpaliła żądanie, czeka na odpowiedź, następnie odpala kolejne żądanie, a następnie czeka na odpowiedź ... itd. Oczywiście złożone witryny z Wiele skryptów JavaScript wymaga od przeglądarki dużej ilości przetwarzania, ale zależy to od pobieranego kodu JavaScript, więc przynajmniej na początku opóźnienia dziedziczone po HTTP / 1.1 powodują problemy. Zazwyczaj serwer nie jest

Tak więc jednym z głównych problemów w dzisiejszym Internecie jest opóźnienie w wysyłaniu żądań między przeglądarką a serwerem. Może to trwać tylko dziesiątki, a może setki milisekund, co może wydawać się niewiele, ale sumują się i często stanowią najwolniejszą część przeglądania sieci - zwłaszcza, że ​​witryny stają się bardziej złożone i wymagają dodatkowych zasobów (w miarę ich uzyskiwania) oraz dostępu do Internetu coraz częściej za pośrednictwem telefonów komórkowych (z mniejszymi opóźnieniami niż łącze szerokopasmowe).

Jako przykład załóżmy, że istnieje 10 zasobów, które strona internetowa musi załadować po załadowaniu samego kodu HTML (co jest bardzo małą witryną według dzisiejszych standardów, ponieważ ponad 100 zasobów jest powszechnych, ale zachowamy prostotę i pójdziemy z tym) przykład). Powiedzmy, że każde żądanie przechodzi przez Internet do serwera WWW iz powrotem w ciągu 100 ms, a czas przetwarzania na obu końcach jest pomijalny (dla uproszczenia powiedzmy 0). Ponieważ musisz wysyłać każdy zasób i czekać na odpowiedź pojedynczo, pobranie całej witryny zajmie 10 * 100 ms = 1000 ms lub 1 sekundę.

Aby obejść ten problem, przeglądarki zazwyczaj otwierają wiele połączeń z serwerem internetowym (zwykle 6). Oznacza to, że przeglądarka może odpalać wiele żądań w tym samym czasie, co jest znacznie lepsze, ale kosztem złożoności związanej z koniecznością konfigurowania i zarządzania wieloma połączeniami (co ma wpływ zarówno na przeglądarkę, jak i na serwer). Kontynuujmy poprzedni przykład i powiedzmy, że istnieją 4 połączenia i dla uproszczenia powiedzmy, że wszystkie żądania są równe. W takim przypadku możesz podzielić żądania na wszystkie cztery połączenia, więc dwa będą miały 3 zasoby do zdobycia, a dwa będą miały 2 zasoby, aby uzyskać w sumie dziesięć zasobów (3 + 3 + 2 + 2 = 10). W takim przypadku najgorszym przypadkiem są 3 rundy lub 300 ms = 0,3 sekundy - dobra poprawa, ale ten prosty przykład nie obejmuje kosztów zestawienia tych wielu połączeń,

HTTP / 2 umożliwia wysyłanie wielu żądań na tym samympołączenie - więc nie musisz otwierać wielu połączeń, jak opisano powyżej. Twoja przeglądarka może więc powiedzieć „Daj mi ten plik CSS. Daj mi ten plik JavaScript. Daj mi obraz1.jpg. Daj mi obraz2.jpg ... itd.” aby w pełni wykorzystać jedno połączenie. Ma to oczywistą zaletę w zakresie wydajności, polegającą na tym, że nie opóźnia wysyłania żądań oczekujących na wolne połączenie. Wszystkie te żądania przechodzą przez Internet do serwera (prawie) równolegle. Serwer odpowiada każdemu z nich, a następnie zaczynają wracać. W rzeczywistości jest jeszcze potężniejszy, ponieważ serwer sieciowy może odpowiadać na nie w dowolnej kolejności i odsyłać pliki w innej kolejności, a nawet rozbijać każdy żądany plik na części i mieszać pliki razem.problem z blokowaniem głowicy linii ). Następnie przeglądarka internetowa ma za zadanie złożyć wszystkie elementy razem. W najlepszym przypadku (zakładając brak ograniczeń przepustowości - patrz poniżej), jeśli wszystkie 10 żądań jest odpalanych prawie na raz równolegle i serwer natychmiast odpowiada, oznacza to, że w zasadzie masz jedną podróż w obie strony lub 100 ms lub 0,1 sekundy, aby pobierz wszystkie 10 zasobów. I nie ma to żadnych wad, które miały wiele połączeń dla HTTP / 1.1! Jest to również znacznie bardziej skalowalne, gdy zasoby w każdej witrynie rosną (obecnie przeglądarki otwierają do 6 równoległych połączeń w protokole HTTP / 1.1, ale czy powinno to rosnąć, gdy witryny stają się bardziej złożone?).

Ten diagram pokazuje różnice, jest też wersja animowana .

Uwaga: HTTP / 1.1 ma koncepcję pipeliningu, która umożliwia również wysyłanie wielu żądań jednocześnie. Jednak nadal musiały być zwracane w całości w kolejności, w jakiej zostały poproszone, więc nie są tak dobre jak HTTP / 2, nawet jeśli koncepcyjnie jest podobny. Nie wspominając o tym, że jest to tak słabo obsługiwane zarówno przez przeglądarki, jak i serwery, że jest rzadko używane.

Jedną z rzeczy podkreślonych w poniższych komentarzach jest wpływ przepustowości na nas tutaj. Oczywiście twoje połączenie internetowe jest ograniczone przez to, ile możesz pobrać, a HTTP / 2 tego nie rozwiązuje. Jeśli więc te 10 zasobów omówionych w powyższych przykładach to masywne obrazy o jakości do druku, pobieranie ich nadal będzie powolne. Jednak w przypadku większości przeglądarek internetowych przepustowość jest mniejszym problemem niż opóźnienie. Więc jeśli te dziesięć zasobów to małe elementy (szczególnie zasoby tekstowe, takie jak CSS i JavaScript, które można spakować za pomocą gzipa, aby były małe), co jest bardzo powszechne w witrynach internetowych, przepustowość nie jest tak naprawdę problemem - to sama ilość zasobów, która często jest problem i protokół HTTP / 2 stara się go rozwiązać. Z tego powodu konkatenacja jest używana w HTTP / 1.1 jako kolejne obejście, więc na przykład wszystkie CSS są często łączone w jeden plik:anty-wzorzec pod HTTP / 2 - choć są też argumenty przeciwko całkowitemu zniesieniu go).

Ujmując to jako przykład z prawdziwego świata: załóżmy, że musisz zamówić 10 artykułów w sklepie z dostawą do domu:

  • HTTP / 1.1 z jednym połączeniem oznacza, że ​​musisz zamawiać je pojedynczo i nie możesz zamówić następnego elementu, dopóki nie nadejdzie ostatni. Możesz zrozumieć, że przebycie wszystkiego zajęłoby tygodnie.

  • HTTP / 1.1 z wieloma połączeniami oznacza, że ​​możesz mieć (ograniczoną) liczbę niezależnych zamówień w ruchu w tym samym czasie.

  • HTTP / 1.1 z potokiem oznacza, że ​​możesz poprosić o wszystkie 10 elementów jeden po drugim bez czekania, ale wtedy wszystkie dotrą w określonej kolejności, o którą prosiłeś. A jeśli jednego produktu nie ma w magazynie, musisz na to poczekać, zanim otrzymasz zamówione produkty - nawet jeśli te późniejsze produkty są rzeczywiście w magazynie! Jest to trochę lepsze, ale nadal podlega opóźnieniom, a powiedzmy, że większość sklepów i tak nie obsługuje tego sposobu zamawiania.

  • HTTP / 2 oznacza, że ​​możesz zamówić swoje produkty w dowolnej kolejności - bez żadnych opóźnień (podobnie jak powyżej). Sklep wyśle ​​je, gdy będą gotowe, więc mogą przybyć w innej kolejności, niż prosiłeś, a nawet podzielić przedmioty, aby niektóre części tego zamówienia dotarły jako pierwsze (więc lepiej niż powyżej). Ostatecznie powinno to oznaczać, że 1) wszystko jest ogólnie szybsze i 2) można rozpocząć pracę nad każdym otrzymanym produktem („och, to nie jest tak miłe, jak myślałem, że może być, więc może chciałbym zamówić coś innego lub zamiast tego” ).

Oczywiście nadal ogranicza Cię rozmiar furgonetki listonosza (przepustowość), więc mogą być zmuszeni zostawić niektóre paczki z powrotem w sortowni do następnego dnia, jeśli są pełne na ten dzień, ale rzadko jest to problem w porównaniu do opóźnienia w faktycznym wysłaniu zamówienia w obie strony. Większość przeglądania stron internetowych polega na wysyłaniu małych liter w tę iz powrotem zamiast dużych paczek.

Mam nadzieję, że to pomoże.

Barry Pollard
źródło
8
Niesamowite wyjaśnienie. Przykład jest tym, czego potrzebowałem, aby to uzyskać. Tak więc w HTTP / 1.1 jest strata czasu między oczekiwaniem na nadejście odpowiedzi a wysłaniem następnego żądania. Protokół HTTP / 2 rozwiązuje ten problem. Dziękuję Ci.
user3448600
1
Ale myślę, że szorstkie. Mogłem po prostu poprosić mnie o dodanie informacji o przepustowości - co z przyjemnością zrobię i zrobię po zakończeniu tej dyskusji. Jednak przepustowość IMHO nie jest tak dużym problemem przy przeglądaniu stron internetowych (przynajmniej w świecie zachodnim) - opóźnienia tak. A HTTP / 2 poprawia opóźnienia. Większość stron internetowych składa się z wielu małych zasobów i nawet jeśli masz odpowiednią przepustowość, aby je pobrać (jak to często robią ludzie), będzie działać wolno z powodu opóźnień w sieci. W przypadku dużych zasobów przepustowość staje się coraz większym problemem. Zgadzam się, że te witryny z ogromnymi obrazami i innymi zasobami mogą nadal osiągać limit przepustowości.
Barry Pollard
1
HTTP nie powinien być używany do wymuszania zamawiania - ponieważ nie daje takich gwarancji. Za pomocą protokołu HTTP / 2 możesz zasugerować priorytet dostawy, ale nie zamówienie. Również jeśli jeden z zasobów JavaScript jest buforowany, a drugi nie, protokół HTTP nie może wpłynąć nawet na priorytet. Zamiast tego powinieneś użyć porządkowania w HTML w połączeniu z odpowiednim użyciem async lub defer ( growwiththeweb.com/2014/02/async-vs-defer-attributes.html ) lub biblioteki takiej jak require.js.
Barry Pollard
1
Świetne wyjaśnienie. Dzięki!
hmacias
2
Dzieje się tak, ponieważ HTTP / 1.1 jest strumieniem tekstu, a HTTP / 2 jest oparty na pakietach - cóż, w HTTP / 2 nazywane są one ramkami, a nie pakietami. Tak więc w HTTP / 2 każda ramka może być oznaczona jako strumień, który umożliwia przeplatanie ramek. W HTTP / 1.1 nie ma takiej koncepcji, ponieważ jest to po prostu seria linii tekstu dla nagłówka, a następnie treści. Więcej szczegółów tutaj: stackoverflow.com/questions/58498116/…
Barry Pollard
4

Simple Ans ( źródło ):

Multipleksowanie oznacza, że ​​Twoja przeglądarka może wysyłać wiele żądań i odbierać wiele odpowiedzi „w pakiecie” w jednym połączeniu TCP. Dlatego obciążenie związane z wyszukiwaniem DNS i uzgadnianiem jest zapisywane dla plików pochodzących z tego samego serwera.

Złożone / szczegółowe odpowiedzi:

Spójrz na odpowiedź udzieloną przez @BazzaDP.

Revanth Kumar
źródło
1
można to osiągnąć używając pipeliningu również w http 1.1. Głównym celem multipleksowania HTTP2 jest, aby nie czekać na odpowiedzi w uporządkowany sposób
Dhairya Lakhera
4

Multipleksowanie w protokole HTTP 2.0 to rodzaj relacji między przeglądarką a serwerem, który wykorzystuje pojedyncze połączenie do równoległego dostarczania wielu żądań i odpowiedzi, tworząc w tym procesie wiele pojedynczych ramek.

Multipleksowanie zrywa ze ścisłą semantyką żądanie-odpowiedź i umożliwia relacje jeden do wielu lub wiele do wielu.

Proces wymiany HTTP1 VS HTTP2

Juanma Menendez
źródło
Twój przykład multipleksowania HTTP / 2 tak naprawdę nie pokazuje multipleksowania. Scenariusz na Twoim diagramie przedstawia potokowanie HTTP, które zostało wprowadzone w HTTP / 1.1.
ich5003
@ ich5003 Jest to multipleksowanie, ponieważ wykorzystuje pojedyncze połączenie. Ale prawdą jest również, że nie są tam przedstawione przypadki wysłania kilku odpowiedzi na jedno żądanie.
Juanma Menendez
1
co próbuję powiedzieć, że scenariusz pokazany powyżej jest również osiągalny tylko przy użyciu potoku HTTP.
ich5003
Uważam, że źródłem nieporozumień jest tutaj kolejność żądania / odpowiedzi na schemacie po prawej stronie - wyświetlają one specjalny przypadek multipleksowania w HTTP / 2, który można również osiągnąć przez potokowanie w HTTP / 1.1. Gdyby kolejność odpowiedzi na diagramie była inna niż kolejność żądań, nie doszłoby do zamieszania.
raiks
4

Poproś o multipleksowanie

HTTP / 2 może wysyłać wiele żądań danych równolegle przez jedno połączenie TCP. Jest to najbardziej zaawansowana funkcja protokołu HTTP / 2, ponieważ umożliwia asynchroniczne pobieranie plików internetowych z jednego serwera. Większość nowoczesnych przeglądarek ogranicza połączenia TCP do jednego serwera. Zmniejsza to dodatkowy czas podróży w obie strony (RTT), dzięki czemu Twoja witryna ładuje się szybciej bez żadnej optymalizacji i sprawia, że ​​fragmentowanie domeny jest niepotrzebne.

wprowadź opis obrazu tutaj

Sandeep Patel
źródło
1

Ponieważ odpowiedź @Juanma Menendez jest poprawna, a jego diagram jest zagmatwany, postanowiłem go ulepszyć, wyjaśniając różnicę między multipleksowaniem a potokiem, pojęcia, które często są ze sobą powiązane.

Pipelining (HTTP / 1.1)

Wiele żądań jest wysyłanych przez to samo połączenie HTTP. Odpowiedzi są odbierane w tej samej kolejności. Jeśli pierwsza odpowiedź zajmuje dużo czasu, inne muszą czekać w kolejce. Podobnie do potokowania procesora, w którym instrukcja jest pobierana, podczas gdy inna jest dekodowana. Wiele instrukcji jest w locie w tym samym czasie, ale ich kolejność zostaje zachowana.

Multipleksowanie (HTTP / 2)

Wiele żądań jest wysyłanych przez to samo połączenie HTTP. Odpowiedzi są odbierane w dowolnej kolejności. Nie trzeba czekać na powolną odpowiedź, która blokuje innych. Podobnie do wykonywania instrukcji poza kolejnością w nowoczesnych procesorach.

Mam nadzieję, że ulepszony obraz wyjaśnia różnicę:

Standardowy przepływ HTTP / 1.1 / Pipelining / Multipleksowanie

raiks
źródło