http-keep-alive в современную эпоху - PullRequest
91 голосов
/ 10 ноября 2010

Так, по словам автора haproxy, который знает кое-что о http:

Keep-alive был изобретен, чтобы уменьшить процессор использование на серверах, когда процессоров было 100 раз медленнее. Но то, что не сказано, это что постоянные соединения потребляют много памяти, пока не используется кем-либо, кроме клиента, который открыл их. Сегодня в 2009 году процессоры очень дешево и память все еще ограничена до нескольких гигабайт по архитектуре или цена. Если сайт нуждается сохранить, есть реальная проблема. Высоконагруженные сайты часто отключают поддерживать в живых, чтобы поддержать максимум количество одновременных клиентов. реальная обратная сторона отсутствия поддержки немного увеличенная задержка получать объекты. Браузеры удваивают количество одновременных подключений на не поддерживающие активность сайты для компенсации это.

(из http://haproxy.1wt.eu/)

Соответствует ли это опыту других народов? т.е. без поддержки активности - результат едва заметен сейчас? (вероятно, стоит отметить, что с веб-сокетами и т. д. - соединение в любом случае остается «открытым» независимо от состояния поддержки активности - для очень отзывчивых приложений). Является ли эффект более значительным для людей, удаленных от сервера, или если при загрузке страницы загружается много артефактов с одного хоста? (Я думаю, что такие вещи, как CSS, изображения и JS все чаще приходят из CDN, дружественных к кешу).

Мысли?

(не уверен, что это вещь serverfault.com, но я не буду пересекать пост, пока кто-нибудь не скажет мне переместить его туда).

Ответы [ 4 ]

139 голосов
/ 10 ноября 2010

Привет, так как я являюсь автором этой цитаты, я отвечу: -)

На больших сайтах есть две большие проблемы: одновременные соединения и задержка.Одновременное соединение вызывается медленными клиентами, которые загружают контент в течение многих лет, и состояниями неактивного соединения.Эти состояния простоя соединения вызваны повторным использованием соединения для выборки нескольких объектов, известных как keep-alive, которые дополнительно увеличиваются за счет задержки.Когда клиент находится очень близко к серверу, он может интенсивно использовать соединение и гарантировать, что он почти никогда не простаивает.Однако, когда последовательность заканчивается, никому нет дела до быстрого закрытия канала, и соединение остается открытым и неиспользованным в течение длительного времени.Вот почему многие люди предлагают использовать очень низкий тайм-аут активности.На некоторых серверах, таких как Apache, минимальное время ожидания, которое вы можете установить, составляет одну секунду, и часто слишком много, чтобы выдерживать высокие нагрузки: если перед вами 20000 клиентов, и они выбирают в среднем один объект каждую секунду, вы будетеиметь эти 20000 постоянных соединений.20000 одновременных соединений на сервере общего назначения, таком как Apache, огромны, потребуют от 32 до 64 ГБ ОЗУ в зависимости от того, какие модули загружены, и вы, вероятно, не надеетесь подняться намного выше, даже добавив ОЗУ.На практике для 20000 клиентов вы можете даже увидеть 40000–60000 одновременных подключений на сервере, потому что браузеры попытаются установить 2–3 подключения, если у них будет много объектов для извлечения.

Если вы закрываете подключение после каждогообъект, количество одновременных подключений резко упадет.На самом деле, он снизится на коэффициент, соответствующий среднему времени загрузки объекта за время между объектами.Если вам нужно 50 мс для загрузки объекта (миниатюрная фотография, кнопка и т. Д.), И вы загружаете в среднем 1 объект в секунду, как указано выше, то у вас будет только 0,05 соединения на клиента, что составляет всего 1000одновременные соединения для 20000 клиентов.

Теперь время для установления новых соединений будет иметь значение.Дальние удаленные клиенты будут испытывать неприятные задержки.В прошлом браузеры использовали большое количество одновременных подключений, когда keep-alive был отключен.Я помню цифры 4 на MSIE и 8 на Netscape.Это действительно разделило бы среднюю задержку на объект на такую ​​величину.Теперь, когда keep-alive присутствует везде, мы больше не видим таких больших цифр, потому что это еще больше увеличивает нагрузку на удаленные серверы, а браузеры заботятся о защите инфраструктуры Интернета.

Это означает, что сВ современных браузерах усложнить не поддерживающие поддержку сервисы так же быстро, как и поддерживающие.Кроме того, некоторые браузеры (например, Opera) используют эвристику, чтобы попытаться использовать конвейеризацию.Конвейерная обработка - это эффективный способ использования keep-alive, поскольку он практически исключает задержки, отправляя несколько запросов, не ожидая ответа.Я пробовал это на странице с 100 маленькими фотографиями, и первый доступ примерно в два раза быстрее, чем без поддержки активности, но следующий доступ примерно в 8 раз быстрее, потому что ответы настолько малы, что учитываются только задержки (только«304» ответов).

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

По этой причине некоторые сайты, которым необходимо установить серверы общего назначения, такие как Apache на лицевой стороне, и которые должны поддерживать большое количество клиентов, обычно отключаютв живых.И чтобы заставить браузеры увеличивать количество подключений, они используют несколько доменных имен, чтобы загрузки могли быть распараллелены.Это особенно проблематично на сайтах, интенсивно использующих SSL, потому что настройка соединения еще выше, так как существует еще один прием в оба конца.

В настоящее время чаще всего наблюдается, что такие сайты предпочитают устанавливать легкие интерфейсы, такие как haproxy или nginx, которые без проблем обрабатывают от десятков до сотен тысяч одновременных соединений, они поддерживают поддержку активности на стороне клиента и отключают это на стороне Apache. С этой стороны, стоимость установления соединения практически равна нулю с точки зрения процессора, и совсем не заметна с точки зрения времени. Таким образом, это обеспечивает лучшее из обоих миров: низкую задержку из-за поддержания активности с очень малым временем ожидания на стороне клиента и малым количеством соединений на стороне сервера. Все счастливы: -)

Некоторые коммерческие продукты дополнительно улучшают это, повторно используя соединения между балансировщиком нагрузки на передней панели и сервером и мультиплексируя все клиентские соединения через них. Когда серверы находятся близко к LB, усиление не намного выше, чем в предыдущем решении, но часто требуется адаптация приложения, чтобы гарантировать отсутствие риска пересечения сеансов между пользователями из-за неожиданного совместного использования соединения между несколькими пользователями. , В теории это никогда не должно происходить. Реальность сильно отличается: -)

22 голосов
/ 26 декабря 2013

За годы, прошедшие с тех пор, как это было написано (и размещено здесь на stackoverflow), у нас теперь есть такие серверы, как nginx, популярность которых растет.

Например, nginx может хранить открытые 10 000 соединений keep-alive в одном процессе с объемом оперативной памяти всего 2,5 МБ (мегабайт). На самом деле легко удерживать открытыми несколько тысяч соединений с очень небольшим объемом ОЗУ, и единственными ограничениями, на которые вы попадете, будут другие ограничения, такие как количество дескрипторов открытых файлов или соединений TCP.

Keep-alive был проблемой не из-за каких-либо проблем с самой спецификацией keep-alive, а из-за модели масштабирования на основе процессов Apache и keep-alives, взломанных на сервер, архитектура которого не предназначена для размещения это.

Особенно проблематичным является Apache Prefork + mod_php + keep-alives. Это модель, в которой каждое отдельное соединение будет продолжать занимать всю оперативную память, которую занимает PHP-процесс, даже если он полностью простаивает и остается открытым только для поддержания активности. Это не масштабируется. Но серверы не должны быть спроектированы таким образом - нет особой причины, по которой серверу нужно хранить каждое поддерживающее соединение соединение в отдельном процессе (особенно, если каждый такой процесс не имеет полноценного интерпретатора PHP). PHP-FPM и модель обработки сервера на основе событий, такая как в nginx, решают проблему элегантно.

Обновление 2015:

SPDY и HTTP / 2 заменяют функцию поддержки активности HTTP чем-то еще лучшим: возможность не только поддерживать соединение и создавать по нему несколько запросов и ответов, но и мультиплексировать их, чтобы ответы можно было отправлять в любом порядке и параллельно, а не только в том порядке, в котором они были запрошены. Это предотвращает медленные ответы, блокирующие более быстрые, и устраняет соблазн для браузеров держать открытыми несколько параллельных подключений к одному серверу. Эти технологии дополнительно подчеркивают недостатки подхода mod_php и преимущества чего-то вроде основанного на событиях (или, по крайней мере, многопоточного) веб-сервера в сочетании с чем-то вроде PHP-FPM.

2 голосов
/ 11 апреля 2013

Очень длинные keep-alive могут быть полезны, если вы используете CDN "pull-origin", такой как CloudFront или CloudFlare. Фактически, это может работать быстрее, чем отсутствие CDN, даже если вы обслуживаете полностью динамический контент.

Если вы долгое время сохраняете живые данные таким образом, что каждый PoP в основном имеет постоянное соединение с вашим сервером, то при первом посещении вашего сайта пользователи могут выполнять быстрое TCP-установление соединения с локальным PoP вместо медленного установления связи с вами. (Самому свету требуется около 100 мс, чтобы обойти весь мир через оптоволокно, и для установления TCP-соединения требуется три пакета, которые должны быть переданы туда и обратно. Для SSL требуется три круговые поездки .)

2 голосов
/ 10 ноября 2010

Насколько я понимаю, это не имеет ничего общего с процессором, но задержка при открытии повторяющихся сокетов на другой стороне мира.даже если у вас бесконечная пропускная способность, задержка подключения замедлит весь процесс.усиливается, если на вашей странице есть десятки объектов.даже постоянное соединение имеет задержку запроса / ответа, но оно уменьшается, когда у вас в среднем 2 сокета, один должен передавать данные, а другой - блокировать.Кроме того, маршрутизатор никогда не будет предполагать, что сокет подключается, прежде чем разрешить вам писать в него.Требуется полное рукопожатие.Опять же, я не претендую на звание эксперта, но я всегда так видел.что действительно здорово, так это полностью протокол ASYNC (нет, не полностью больной протокол).

...