что такое keep alive

Соединяй и властвуй. Нестандартный взгляд на keep-alive

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive

Большинство современных серверов поддерживает соединения keep-alive. Если на страницах много медиаконтента, то такое соединение поможет существенно ускорить их загрузку. Но мы попробуем использовать keep-alive для куда менее очевидных задач.

How it works

Прежде чем переходить к нестандартным способам применения, расскажу, как работает keep-alive. Процесс на самом деле прост донельзя — вместо одного запроса в соединении посылается несколько, а от сервера приходит несколько ответов. Плюсы очевидны: тратится меньше времени на установку соединения, меньше нагрузка на CPU и память. Количество запросов в одном соединении, как правило, ограничено настройками сервера (в большинстве случаев их не менее нескольких десятков). Схема установки соединения универсальна:

1. В случае с протоколом HTTP/1.0 первый запрос должен содержать заголовок **Connection: keep-alive**.
Если используется HTTP/1.1, то такого заголовка может не быть вовсе, но некоторые серверы будут автоматически закрывать соединения, не объявленные постоянными. Также, к примеру, может помешать заголовок **Expect: 100-continue**. Так что рекомендуется принудительно добавлять keep-alive к каждому запросу — это поможет избежать ошибок.

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive
Expect принудительно закрывает соединение

2. Когда указано соединение keep-alive, сервер будет искать конец первого запроса. Если в запросе не содержится данных, то концом считается удвоенный CRLF (это управляющие символы \r\n, но зачастую срабатывает просто два \n). Запрос считается пустым, если у него нет заголовков Content-Length,Transfer-Encoding, а также в том случае, если у этих заголовков нулевое или некорректное содержание. Если они есть и имеют корректное значение, то конец запроса — это последний байт контента объявленной длины.

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive
За последним байтом объявленного контента может сразу идти следующий запрос

3. Если после первого запроса присутствуют дополнительные данные, то для них повторяются соответствующие шаги 1 и 2, и так до тех пор, пока не закончатся правильно сформированные запросы.

Иногда даже после корректного завершения запроса схема keep-alive не отрабатывает из-за неопределенных магических особенностей сервера и сценария, к которому обращен запрос. В таком случае может помочь принудительная инициализация соединения путем передачи в первом запросе HEAD.

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive
Запрос HEAD запускает последовательность keep-alive

Тридцать по одному или один по тридцать?

Как бы забавно это ни звучало, но первый и самый очевидный профит — это возможность ускориться при некоторых видах сканирования веб-приложений. Разберем простой пример: нам нужно проверить определенный XSS-вектор в приложении, состоящем из десяти сценариев. Каждый сценарий принимает по три параметра.

Я накодил небольшой скрипт на Python, который пробежится по всем страницам и проверит все параметры по одному, а после выведет уязвимые сценарии или параметры (сделаем четыре уязвимые точки) и время, затраченное на сканирование.

Источник

Грабли на пути к keep-alive

Увеличение активности обмена данными между микросервисами зачастую является проблемой в архитектуре современных IT решений. Выжать максимум и выжить любой ценой — серьёзный вызов для любой разработки. Поэтому поиск оптимальных решений — это не прекращающийся процесс. В статье кратко изложены проблемы, которые могут возникнуть при высоконагруженном использовании http запросов и пути их обхода.

Эта история начинается с ошибки. Как-то мы проводили нагрузочное тестирование, основным элементом которого было выполнение большого количества коротких http запросов. Клиент, написаный под netcore 2.2, начиная с какого-то момента, выдавал System.Net.Sockets.SocketException: Address already in use. Достаточно быстро выяснилось, что на клиенте не успевали освобождаться порты, и в какой-то момент система получала отказ в открытии нового. Теперь, если перейти к коду, проблема была в использовании старого подхода с классом HttpWebRequest и конструкции:

Казалось бы, мы высвобождаем ресурс, и порт должен быть освобожден своевременно. Однако netstat сигнализировал о быстром росте количества портов в состоянии TIME_WAIT. Это состояние означает ожидание закрытия соединения (и возможно получение потерянных данных). Как следствие порт может находится в нем 1-2 минуты. Данная проблема рассмотрена довольно подробно во многих статьях (Проблемы с очередью TIME_WAIT, История о TIME_WAIT). Все же это означает, что dotnet «честно» пытается закрыть соединение, а дальнейшее происходит уже по вине настроек таймаута в системе.

Почему так происходит и как с этим бороться

Не буду рассказывать про keep-alive. Об этом можно почитать самостоятельно. Целью статьи является попытка обойти грабли, заботливо разложенные на пути разработчика. Согласно msdn, свойство KeepAlive класса HttpWebRequest по умолчанию равно true. То есть все это время HttpWebRequest «обманывал» сервер, предлагая ему поддержать соединение, после чего сам же его разрывал. Если быть точнее, HttpWebRequest с настройками по умолчанию не отправлял заголовок «Connection: keep-alive», просто этот режим подразумевается в стандарте HTTP/1.1. Первое, что следовало попробовать, это принудительно отключить KeepAlive. Если установить HttpWebRequest.KeepAlive = false, то в запросе появляется заголовок «Connection: close». Надо признать, что на тестовом стенде это полностью решило проблему. В качестве сервера был настроен nginx со статической страницей.

Тестировался следующий код:

Однако при попытке запустится на серверном железе, при больших нагрузках (свыше 1000 запросов в секунду) этот код вновь начал выдавать те же ошибки. Только теперь порты находились в состоянии CLOSE_WAIT, LAST_ACK. Это пред-финальные состояния закрытия соединения, когда клиент ждет подтверждение от инициатора закрытия. Такое поведение сигнализирует о том, что клиент начинает «захлебываться» вновь открываемыми соединениями.

Закрывать нельзя, переиспользовать

Действительно, чтобы добиться максимальной производительности, соединение нужно переиспользовать. Для этого необходимо включить режим keep-alive и взять класс HttpClient. Как именно он работает и как лучше его использовать стоит почитать здесь и здесь.

Другой вопрос заключается в том, как убедится, что соединения переиспользуются? Существование одного keep-alive соединения регулируется двумя основными параметрами на сервере nginx:

Если просматривать соединения в netstat или wireshark, то при больших нагрузках открытые порты на клиенте также будут стремительно меняться. Только выставив keepalive_requests в большие значения (> 1000) можно увидеть, что все работает как надо.

Вывод

Если вы не используете http запросы в высоконагруженном режиме, то вам подойдет любой вариант. Вряд ли вы успеете исчерпать все порты. Если же в вашем приложении переиспользовать соединения смысла нет, например вы редко повторно обращаетесь к серверу, то стоит сознательно отключать keep-alive. Также keep-alive стоит использовать правильно и с осторожностью при большом потоке запросов, регулируя время жизни соединения в зависимости от частоты повторных обращений к серверу.

И напоследок немного тестовых сравнений производительности:

Сервер nginx настроен с параметрами:

Источник

Русские Блоги

Что такое HTTP Keep-Alive? Как это работает?

HTTP Keep-Alive

В первые дни http каждый http-запрос требовал открыть соединение через сокет tpc, а затем отключить соединение tcp после его однократного использования.

Использование keep-alive может улучшить это состояние, то есть можно непрерывно отправлять несколько данных без отключения по TCP-соединению. Используя механизм keep-alive, количество соединений TCP-соединений может быть уменьшено, что также означает, что состояние соединения TIME_WAIT может быть уменьшено, что повышает производительность и повышает пропускную способность сервера httpd (меньшее количество соединений tcp означает меньшее количество вызовов ядра системы, сокетов Принять () и закрыть () вызовы).

Тем не менее,keep-aliveЭто не бесплатный обед. Длинные TCP-соединения могут легко привести к неэффективному использованию системных ресурсов. Неправильно настроенная поддержка активности может иногда стоить дороже, чем повторное использование соединений. Поэтому важно правильно установить время ожидания активности.

keepalvie timeout

Демон Httpd обычно предоставляет параметр установки времени ожидания активности. Например, keepinlive_timeout для nginx и KeepAliveTimeout для Apache. Это значение времени keepalive_timout означает, что TCP-соединение, сгенерированное http, должно удерживать секунду keepalive_timeout после передачи последнего ответа, прежде чем оно начнет закрывать соединение.

Когда демон httpd заканчивает отправку ответа, он должен немедленно предпринять попытку закрыть соответствующее TCP-соединение. После установки keepalive_timeout демон httpd захочет сказать: «Подождите немного и посмотрите, запросил ли браузер его». Это время keepalive_timeout. Если демон не получает запрос http от браузера в течение этого времени ожидания, соединение http закрывается.

Напишите скрипт ниже для удобного тестирования:

1. Когда время keepalive_timeout равно 0, то есть когда Keep-Alive не включен, жизненный цикл TCP-соединения:

Можно видеть, что без сохранения alive_timeout время, необходимое ресурсу сокета от установления к реальному выпуску, составляет: установление соединения TCP + передача запроса HTTP + выполнение сценария PHP + передача ответа HTTP + закрытие соединения TCP + 2MSL. (Примечание. Время здесь можно использовать только в качестве эталона. Конкретное время в основном определяется пропускной способностью сети и размером ответа.)

2. Когда время keepalive_timeout больше 0, то есть, когда Keep-Alive включен, жизненный цикл TCP-соединения. Для анализа мы установили keepalive_timeout равным 300 с

3. Когда время keepalive_timeout больше 0 и несколько HTTP-ответов отправляются по одному и тому же TCP-соединению. Здесь для анализа мы установили keepalive_timeout равным 180 с.

С помощью этого теста мы хотим выяснить, запускает ли keepalive_timeout таймер с конца первого ответа или заканчивается последний таймер. Результаты теста подтвердили последнее: здесь мы отправляли запрос каждые 120 секунд и отправляли 3 запроса через TCP-соединение.

http keep-alive и tcp keep-alive

То есть, только когда значение nginx keepalive_timeout установлено выше, чем tcp_keepalive_time и последний HTTP-ответ, переданный из этого tcp-соединения, после истечения времени tcp_keepalive_time операционная система отправит пакет обнаружения, чтобы решить, следует ли сбрасывать TCP-соединение. Обычно это не тот случай, если вам не нужно это делать.

keep-alive и TIME_WAIT

Использование http keep-alvie может уменьшить количество серверов TIME_WAIT (поскольку демон httpd сервера активно закрывает соединение). Причина очень проста: по сравнению с включением поддержки активности установлено меньше соединений TCP и, естественно, закрыто меньше соединений TCP.

в конце концов

Я хочу использовать схематическое изображение, чтобы проиллюстрировать разницу между использованием keepalive. Кроме того, http keepalive является результатом сотрудничества между клиентским браузером и демоном httpd сервера, поэтому мы подготовили отдельную статью, чтобы представить использование keepalive в разных ситуациях в разных браузерах.

Источник

Ускорение Работы Сайта — Включение Режима Keep-Alive

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive

Введение

Как работает режим Keep-Alive?

В этом руководстве вы научитесь 4 способам, как включить режим Keep-Alive. Keep-Alive позволяет браузеру пользователя скачивать весь необходимый контент (такой как JavaScript, CSS, изображения, видео и т.д.) через постоянное TCP соединение, вместо создания нескольких запросов для каждого файла. Это обеспечит скорость и производительность, так как браузер вашего посетителя сможет получить все из одного, постоянного HTTP соединения. Простыми словами, Keep-Alive — это форма связи между сервером и браузером способная серьезно уменьшить количество запросов и скорость загрузки страницы. Эта схема позволит вам понять разницу и преимущество режима Keep-Alive:

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive

Преимущества режима Keep-Alive:

После всего этого, можно с уверенностью сказать, что Keep-Alive это отличный способ для уменьшения использования ресурсов сервера, и в то же время увеличения скорости загрузки вашего сайта.

Что вам понадобится

Перед тем, как вы начнете это руководство, вам понадобится следующее:

Шаг 1 — Анализ вашего сайта

Во-первых, вы должны проанализировать ваш сайт с помощью таких инструментов как GTMetrix, чтобы определить включен ли режим Keep-Alive на вашем сервере. Вот результаты после анализа тестовой страницы:

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive

На некоторых серверах или провайдерах услуг хостинга режим Keep-Alive включен по умолчанию. Если ваши результаты выдают 100%, значит вам нет необходимости производить какие-либо действия.

Шаг 2 — Включение режима Keep-Alive

Существует несколько способов включения режима Keep-Alive и их выбор зависит от вашего сервера или провайдера услуг хостинга. Вот несколько вариантов:

Этот метод должен работать на большинстве виртуальных хостингов на базе Linux. В случае, если вы не знаете где найти файл .htaccess, обратитесь к этому руководству.

Вариант 2 — Включение режима Keep-Alive в Apache через файл httpd.conf

Если у вас есть доступ к файлу настроек Apache, вы можете включить режим оттуда. Вот как должны выглядеть настройки:

Если вы не можете найти файл httpd.conf, запустите следующую команду в командной строке:

Вариант 3 — Включение Keep-Alive в NGINX

В NGINX, Keep-Alive по умолчанию обычно включен. Однако в некоторых случаях он может быть выключен. Вы можете включить его используя HttpCoreModule. Найдите значение keepalive_disable, которое в большинстве случаев является причиной его отключения. Перед внесением каких-либо изменений убедитесь, что узнали причину по которой он был отключен.

Вариант 4 — Сервер Windows (IIS)

Если вы используете сервер на базе Windows, вы можете легко включить режим Keep-Alive используя командную строку.

Данная команда включит режим Keep-Alive:

На случай если вы захотите его отключить используйте эту:

Вы также можете обратиться к официальному руководству от Microsoft на эту тему.

Шаг 3 — Проверка изменений

После того, как режим Keep-Alive полностью включен, запустите еще один анализ в GTMetrix или любом другом сайте по анализу производительности. Вот результаты тестового сайта после включения режима Keep-Alive:

что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive

Также можно узнать работает ли Keep-Alive проверив header вашего HTTP. Это может быть сделано через терминал, используя следующую команду:

Часть кода Connection: keep-alive означает, что режим Keep-Alive полностью функционирует.

Заключение

Подводя итог, включение режима Keep-Alive это отличный способ для улучшения скорости и производительности вашего сайта. Постоянное TCP соединение обеспечит быстрое время загрузки и более высокую эффективность, тем самым делая ваших посетителей счастливыми.

Источник

Http запросы — мы все это делаем неправильно

В проекте, над которым я работаю, мы используем огромное количество сторонних библиотек. Многие из них — адаптеры для различных сервисов. Что их объединяет, это то, что они работают с сетью. Json поверх http, soap поверх http, какие-то свои протоколы поверх http. Т.е. все так или иначе используют http. И как ни удивительно, мало кто из них пользуется преимуществами его последней версии. Я не поленился заглянуть в википедию, прошло ровно 14 лет как была принята спецификация http 1.1. И потому я решил обратиться с призывом:
что такое keep alive. Смотреть фото что такое keep alive. Смотреть картинку что такое keep alive. Картинка про что такое keep alive. Фото что такое keep alive

Да, речь пойдет о keep alive. Суть в том, что, начиная с http 1.1, клиент и сервер могут договориться не закрывать установленное tcp-соединение после завершения запроса, а переиспользовать его для следующих запросов. Это нужно потому, что на установку соединения требуется время. Иногда это время больше, чем время самого запроса. И если все серверы уже давным-давно такую возможность поддерживают, а все браузеры и большинство других клиентов её используют, то у разработчиков различных библиотек для популярных языков программирования здесь почему-то пробел.
Рассмотрим простой код на PHP, который последовательно делает 10 запросов к одному серверу:

Это каркас 95% библиотек, обращающихся к сторонним ресурсам. Опция CURLOPT_VERBOSE позволяет видеть в консоли все, что делает библиотека curl во время выполнения скрипта. И самые интересные строчки будут повторяться все 9 запросов (кроме первого):

Как видите, curl оставляет соединение после запроса открытым, но мы его тут же закрываем. Результат печален: 10 запросов создают 10 соединений, скрипт выполняется не менее 17 секунд.

Это говорит о том, что сам curl знаком с http 1.1, а мы мешаем ему нормально работать. Но исправить это очень просто:

Мы просто вынесли создание и удаление дескриптора из цикла, и картина при следующем запуске поменялась:

А время работы сократилось до 5,5 секунд. Конечно, тут я намеренно обращаюсь к статическому файлу. В реальных условиях некоторое время займет формирование запроса. Плюс, если вы используете http без ssl, время соединения будет немного меньше. Тем не менее, постоянные соединения в любом случае дают существенный выигрыш.

Я провел несколько экспериментов, измеряя время, необходимое на 10 запросов по протоколам http и https с использованием отдельных соединений и keep-alive для файлов разного размера с разными пингами до сервера. Брался лучший результат за 5-6 измерений.

evernote.com/favicon.ico, Пинг ≈ 200 ms, размер 27054 байт.

ReconnectKeep-AliveRatio
http1052x
https175,53,1x

twitter.com/favicon.ico, Пинг ≈ 200 ms, размер 1150 байт.

ReconnectKeep-AliveRatio
http4,32,51,7x
https8,52,73,1x

yandex.st/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico, Пинг ≈ 17 ms, размер 1150 байт.

ReconnectKeep-AliveRatio
http0,330,171,9x
https0,80,24x

Цифры говорят сами за себя. Но прелесть даже не в них, а в том, что добиться этого очень просто. Все что вам нужно сделать в случае использования curl — перенести вызов curl_init() из метода, который делает запрос, в конструктор класса (вот один и другой пример, где это легко можно сделать). При этом curl_close() можно выкинуть совсем, ресурсы и так освободятся при завершении запроса. Curl сам держит пул соединений для каждой пары хост и порт, к которым вы обращаетесь, и переоткрывает закрытые соединения.

Надеюсь, мне удалось убедить вас в необходимости обращать на это внимание при разработке библиотек, и показать, насколько это просто реализуется.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *