edytuj: Moja odpowiedź obejmuje tylko oryginalne, niezredagowane pytanie, które dotyczyło tego, czy tego rodzaju rzeczy są typowe w przypadku równoważenia obciążenia / odwrotnych serwerów proxy. Nie jestem pewien, czy nginx / produkt X obsługuje to, 99,9% moich doświadczeń z odwrotnym proxy jest z HAproxy.
Poprawny. HTTP Keep-Alive po stronie klienta, ale nie po stronie serwera.
Czemu?
Jeśli podzielisz kilka szczegółów, szybko zobaczysz, dlaczego jest to korzyść. W tym przykładzie udajmy, że ładujemy stronę www.example.com, a ta strona zawiera 3 obrazy, img [1-3] .jpg.
Przeglądarka ładuje stronę bez Keep-Alive
- Klient nawiązuje połączenie TCP ze stroną www.example.com na porcie 80
- Klient wykonuje żądanie HTTP GET dla „/”
- Serwer wysyła zawartość HTML identyfikatora URI „/” (który zawiera tagi HTML odnoszące się do 3 obrazów)
- Serwer zamyka połączenie TCP
- Klient nawiązuje połączenie TCP ze stroną www.example.com na porcie 80
- Klient wykonuje żądanie HTTP GET dla „/img1.jpg”
- Serwer wysyła obraz
- Serwer zamyka połączenie TCP
- Klient nawiązuje połączenie TCP ze stroną www.example.com na porcie 80
- Klient wykonuje żądanie HTTP GET dla „/img2.jpg”
- Serwer wysyła obraz
- Serwer zamyka połączenie TCP
- Klient nawiązuje połączenie TCP ze stroną www.example.com na porcie 80
- Klient wykonuje żądanie HTTP GET dla „/img3.jpg”
- Serwer wysyła obraz
- Serwer zamyka połączenie TCP
Zauważ, że ustanowiono 4 osobne sesje TCP, a następnie zamknięto.
Przeglądarka ładuje stronę za pomocą Keep-Alive
HTTP Keep-Alive pozwala pojedynczemu połączeniu TCP obsługiwać wiele żądań HTTP, jeden po drugim.
- Klient nawiązuje połączenie TCP ze stroną www.example.com na porcie 80
- Klient wysyła żądanie HTTP GET dla „/”, a także prosi serwer, aby uczynił to sesją HTTP Keep-Alive.
- Serwer wysyła zawartość HTML identyfikatora URI „/” (który zawiera tagi HTML odnoszące się do 3 obrazów)
- Serwer nie zamyka połączenia TCP
- Klient tak i żądanie HTTP GET dla „/img1.jpg”
- Serwer wysyła obraz
- Klient tak i żądanie HTTP GET dla „/img2.jpg”
- Serwer wysyła obraz
- Klient robi i żądanie HTTP GET dla „/img3.jpg”
- Serwer wysyła obraz
- Serwer zamyka połączenie TCP, jeśli nie upłynie więcej żądań HTTP w jego limicie czasu podtrzymania HTTP
Zauważ, że dzięki Keep-Alive tylko 1 połączenie TCP jest ustanawiane i ostatecznie zamykane.
Dlaczego Keep-Alive jest lepszy?
Aby odpowiedzieć na to pytanie, musisz zrozumieć, co jest potrzebne do nawiązania połączenia TCP między klientem a serwerem. Nazywa się to potrójnym uzgadnianiem TCP.
- Klient wysyła pakiet SYN (chronise)
- Serwer odsyła SYN (chronise) ACK (nowledgement), SYN-ACK
- Klient wysyła pakiet ACK (nowledgement)
- Połączenie TCP jest teraz uważane za aktywne zarówno przez klienta, jak i serwer
Sieci mają opóźnienia, więc każdy krok w 3-kierunkowym uzgadnianiu zajmuje określoną ilość czasu. Powiedzmy, że między klientem a serwerem jest 30 ms, wysyłanie pakietów IP w przód iw tył wymagane do nawiązania połączenia TCP oznacza, że ustanowienie połączenia TCP zajmuje 3 x 30 ms = 90 ms.
Może to nie brzmieć dużo, ale jeśli weźmiemy pod uwagę, że w naszym oryginalnym przykładzie musimy ustanowić 4 oddzielne połączenia TCP, to staje się 360ms. Co jeśli opóźnienie między klientem a serwerem wynosi 100 ms zamiast 30 ms? Nasze 4 połączenia trwają 1200ms.
Co gorsza, typowa strona internetowa może wymagać znacznie więcej niż tylko 3 obrazów do załadowania, może istnieć wiele plików CSS, JavaScript, obrazów lub innych plików, które klient musi zażądać. Jeśli strona ładuje 30 innych plików, a opóźnienie klient-serwer wynosi 100 ms, ile czasu spędzamy na nawiązywaniu połączeń TCP?
- Ustanowienie 1 połączenia TCP wymaga 3 x opóźnienia, tj. 3 x 100 ms = 300 ms.
- Musimy to zrobić 31 razy, raz dla strony i kolejne 30 razy dla każdego innego pliku, do którego odwołuje się strona. 31 x 300 ms = 9,3 sekundy.
9,3 sekundy spędziłem na ustanawianiu połączeń TCP w celu załadowania strony internetowej, która odwołuje się do 30 innych plików. I to nawet nie liczy czasu spędzonego na wysyłaniu żądań HTTP i otrzymywaniu odpowiedzi.
Dzięki HTTP Keep-Alive potrzebujemy tylko 1 połączenia TCP, co zajmuje 300ms.
Jeśli HTTP Keep-Alive jest tak świetny, dlaczego nie użyć go również po stronie serwera?
Odwrotne proxy HTTP (takie jak HAproxy) są zazwyczaj wdrażane bardzo blisko serwerów zaplecza, dla których są one proxy. W większości przypadków opóźnienie między zwrotnym serwerem proxy a jego serwerem zaplecza będzie wynosić poniżej 1ms, więc nawiązanie połączenia TCP jest znacznie szybsze niż między klientem.
To tylko połowa tego powodu. Serwer HTTP przydziela określoną ilość pamięci dla każdego połączenia klienta. Dzięki Keep-Alive utrzyma połączenie przy życiu, a przez rozszerzenie utrzyma pewną ilość pamięci używanej na serwerze, dopóki nie zostanie przekroczony limit czasu Keep-Alive, który może wynosić do 15 sekund, w zależności od konfiguracji serwera .
Jeśli więc weźmiemy pod uwagę skutki używania Keep-Alive po stronie serwera zwrotnego proxy HTTP, zwiększamy zapotrzebowanie na pamięć, ale ponieważ opóźnienie między serwerem proxy a serwerem jest tak niskie, nie uzyskujemy żadnej realnej korzyści z skrócenie czasu potrzebnego na potrójny uścisk dłoni TCP, więc zwykle lepiej jest po prostu wyłączyć Keep-Alive między serwerem proxy a serwerem WWW w tym scenariuszu.
Oświadczenie: tak, to wyjaśnienie nie bierze pod uwagę faktu, że przeglądarki zwykle ustanawiają wiele połączeń HTTP z serwerem równolegle. Istnieje jednak ograniczenie liczby połączeń równoległych, które przeglądarka nawiąże z tym samym hostem, i zwykle jest to wciąż wystarczająco małe, aby utrzymać aktywność przy życiu.