редактировать: мой ответ охватывает только исходный неотредактированный вопрос, который был типичным для такого рода вещей в балансировщиках нагрузки / обратных прокси. Я не уверен, что nginx / product X поддерживает это, 99,9% моего опыта обратного проксирования - с HAproxy.
Правильный. HTTP Keep-Alive на стороне клиента, но не на стороне сервера.
Зачем?
Если вы укажете несколько деталей, вы сможете быстро понять, почему это выгодно. Для этого примера давайте представим, что мы загружаем страницу www.example.com, и эта страница содержит 3 изображения, img [1-3] .jpg.
Загрузка страницы браузером без Keep-Alive
- Клиент устанавливает TCP-соединение с www.example.com через порт 80
- Клиент выполняет HTTP-запрос GET для "/"
- Сервер отправляет HTML-содержимое URI "/" (которое включает в себя HTML-теги, ссылающиеся на 3 изображения)
- Сервер закрывает TCP соединение
- Клиент устанавливает TCP-соединение с www.example.com через порт 80
- Клиент выполняет HTTP-запрос GET для "/img1.jpg"
- Сервер отправляет изображение
- Сервер закрывает TCP соединение
- Клиент устанавливает TCP-соединение с www.example.com через порт 80
- Клиент выполняет HTTP-запрос GET для "/img2.jpg"
- Сервер отправляет изображение
- Сервер закрывает TCP соединение
- Клиент устанавливает TCP-соединение с www.example.com через порт 80
- Клиент выполняет HTTP-запрос GET для "/img3.jpg"
- Сервер отправляет изображение
- Сервер закрывает TCP соединение
Обратите внимание, что 4 отдельных сеанса TCP установлены, а затем закрыты.
Загрузка страницы браузером с Keep-Alive
HTTP Keep-Alive позволяет одному TCP-соединению обслуживать несколько HTTP-запросов, один за другим.
- Клиент устанавливает TCP-соединение с www.example.com через порт 80
- Клиент выполняет HTTP-запрос GET для «/», а также просит сервер сделать этот сеанс HTTP Keep-Alive.
- Сервер отправляет HTML-содержимое URI "/" (которое включает в себя HTML-теги, ссылающиеся на 3 изображения)
- Сервер не закрывает TCP соединение
- Клиент делает и HTTP GET запрос для "/img1.jpg"
- Сервер отправляет изображение
- Клиент делает и HTTP-запрос GET для "/img2.jpg"
- Сервер отправляет изображение
- Клиент делает и HTTP GET запрос для "/img3.jpg"
- Сервер отправляет изображение
- Сервер закрывает TCP-соединение, если в течение периода ожидания Keep-Alive HTTP больше не получено ни одного HTTP-запроса
Обратите внимание, что с Keep-Alive только 1 TCP-соединение установлено и в конечном итоге закрыто.
Почему Keep-Alive лучше?
Чтобы ответить на этот вопрос, вы должны понимать, что нужно для установления TCP-соединения между клиентом и сервером. Это называется трехсторонним рукопожатием TCP.
- Клиент отправляет SYN (хронизированный) пакет
- Сервер отправляет обратно SYN (хронологию) ACK (присвоение), SYN-ACK
- Клиент отправляет пакет ACK (nowledgement)
- TCP-соединение теперь считается активным как клиентом, так и сервером
В сетях наблюдается задержка, поэтому каждый шаг трехстороннего рукопожатия занимает определенное время. Допустим, между клиентом и сервером есть 30 мс, отправка IP-пакетов назад и вперед, необходимая для установления TCP-соединения, означает, что для установления TCP-соединения требуется 3 x 30 мс = 90 мс.
Это может показаться не таким уж большим, но если учесть, что в нашем исходном примере нам нужно установить 4 отдельных TCP-соединения, это станет 360 мс. Что если задержка между клиентом и сервером составляет 100 мс, а не 30 мс? Тогда наши 4 соединения требуют 1200 мс для установления.
Хуже того, для загрузки обычной веб-страницы может потребоваться не более 3-х изображений, может быть несколько файлов CSS, JavaScript, изображений или других файлов, которые клиент должен запросить. Если страница загружает 30 других файлов и задержка клиент-сервер составляет 100 мс, сколько времени мы тратим на установление TCP-соединений?
- Для установления 1 TCP-соединения требуется 3 x задержки, т.е. 3 x 100 мс = 300 мс.
- Мы должны сделать это 31 раз, один раз для страницы и еще 30 раз для каждого файла, на который ссылается страница. 31 х 300 мс = 9,3 секунды.
9,3 секунды потратили на установление TCP-соединений для загрузки веб-страницы, которая ссылается на 30 других файлов. И это даже не учитывает время, потраченное на отправку HTTP-запросов и получение ответов.
С HTTP Keep-Alive нам нужно только установить 1 TCP-соединение, которое занимает 300 мс.
Если HTTP Keep-Alive настолько хорош, почему бы не использовать его и на стороне сервера?
Обратные прокси-серверы HTTP (такие как HAproxy) обычно развертываются очень близко к серверным серверам, для которых они проксируют. В большинстве случаев задержка между обратным прокси-сервером и его внутренним сервером будет менее 1 мс, поэтому установление TCP-соединения происходит намного быстрее, чем между клиентом.
Это только половина причины, хотя. HTTP-сервер выделяет определенный объем памяти для каждого клиентского соединения. С Keep-Alive он будет поддерживать соединение активным, и, соответственно, он будет поддерживать определенный объем памяти на сервере до истечения времени ожидания Keep-Alive, которое может достигать 15 с, в зависимости от конфигурации сервера. ,
Поэтому, если мы рассмотрим последствия использования Keep-Alive на стороне сервера обратного прокси-сервера HTTP, мы увеличим потребность в памяти, но поскольку задержка между прокси-сервером и сервером очень мала, мы не получим реальной выгоды от сокращение времени, затрачиваемого на трехстороннее рукопожатие TCP, поэтому в этом случае обычно лучше отключить Keep-Alive между прокси-сервером и веб-сервером.
Отказ от ответственности: да, это объяснение не принимает во внимание тот факт, что браузеры обычно устанавливают несколько HTTP-соединений с сервером параллельно. Тем не менее, существует ограничение на количество параллельных подключений браузера к одному и тому же хосту, и, как правило, оно все еще достаточно мало, чтобы сделать поддержку активности желательной.