Итак, по словам автора haproxy, кто кое-что знает о http:
Keep-alive был изобретен для уменьшения использования ЦП на серверах, когда ЦП были в 100 раз медленнее. Но что не сказано, так это то, что постоянные соединения потребляют много памяти и не могут использоваться никем, кроме клиента, который их открыл. Сегодня, в 2009 году, процессоры очень дешевы, а объем памяти по-прежнему ограничен несколькими гигабайтами из-за архитектуры или цены. Если сайту нужен keep-alive, возникает реальная проблема. Высоконагруженные сайты часто отключают поддержку активности для поддержки максимального количества одновременных клиентов. Реальный недостаток отсутствия keep-alive - это немного увеличенная задержка для выборки объектов. Чтобы компенсировать это, браузеры удваивают количество одновременных подключений к сайтам без поддержки активности.
Соответствует ли это опыту других людей? т.е. без keep-alive - сейчас результат еле заметен? (вероятно, стоит отметить, что с веб-сокетами и т. д. - соединение остается «открытым» независимо от статуса keep-alive - для очень отзывчивых приложений). Будет ли эффект больше для людей, удаленных от сервера, или если при загрузке страницы нужно загрузить много артефактов с одного и того же хоста? (Я думаю, что такие вещи, как CSS, изображения и JS, все чаще поступают из CDN, дружественных к кешу).
Мысли?
(не уверен, что это связано с serverfault.com, но я не буду перекладывать сообщения, пока кто-нибудь не скажет мне переместить его туда).
источник
Ответы:
Привет, раз уж я автор этой цитаты, отвечу :-)
На больших сайтах есть две большие проблемы: одновременные подключения и задержка. Одновременное подключение вызывается медленными клиентами, которым требуется много времени для загрузки содержимого, а также состояниями незанятого подключения. Эти состояния незанятого соединения вызваны повторным использованием соединения для выборки нескольких объектов, известным как keep-alive, что дополнительно увеличивается из-за задержки. Когда клиент находится очень близко к серверу, он может интенсивно использовать соединение и гарантировать, что он почти никогда не простаивает. Однако, когда последовательность заканчивается, никто не заботится о быстром закрытии канала, и соединение остается открытым и не используется в течение длительного времени. Это причина, по которой многие люди предлагают использовать очень низкий тайм-аут проверки активности. На некоторых серверах, таких как Apache, самый низкий тайм-аут, который вы можете установить, составляет одну секунду, и часто его слишком много для выдерживания высоких нагрузок: Если перед вами 20000 клиентов, и они загружают в среднем один объект каждую секунду, у вас будут постоянно установлены эти 20000 соединений. 20000 одновременных подключений на сервере общего назначения, таком как Apache, огромны, потребуют от 32 до 64 ГБ ОЗУ в зависимости от того, какие модули загружены, и вы, вероятно, не можете надеяться подняться намного выше, даже добавив ОЗУ. На практике для 20000 клиентов вы можете даже увидеть от 40000 до 60000 одновременных соединений на сервере, потому что браузеры будут пытаться установить от 2 до 3 соединений, если у них есть много объектов для выборки. и вы, вероятно, не можете надеяться подняться намного выше, даже добавив RAM. На практике для 20000 клиентов вы можете даже увидеть от 40000 до 60000 одновременных соединений на сервере, потому что браузеры будут пытаться установить от 2 до 3 соединений, если у них есть много объектов для выборки. и вы, вероятно, не можете надеяться подняться намного выше, даже добавив RAM. На практике для 20000 клиентов вы можете даже увидеть от 40000 до 60000 одновременных соединений на сервере, потому что браузеры будут пытаться установить от 2 до 3 соединений, если у них есть много объектов для выборки.
Если вы закроете соединение после каждого объекта, количество одновременных соединений резко упадет. В самом деле, оно снизится на коэффициент, соответствующий среднему времени загрузки объекта по времени между объектами. Если вам нужно 50 мс для загрузки объекта (миниатюрная фотография, кнопка и т. Д.), И вы загружаете в среднем 1 объект в секунду, как указано выше, тогда у вас будет только 0,05 соединения на одного клиента, что составляет всего 1000 одновременных подключений для 20000 клиентов.
Теперь пришло время установить новые связи. У удаленных клиентов возникнет неприятная задержка. Раньше браузеры использовали большое количество одновременных подключений, когда функция keep-alive была отключена. Я помню цифры 4 на MSIE и 8 на Netscape. Это действительно разделило бы среднюю задержку для каждого объекта на столько же. Теперь, когда keep-alive присутствует повсюду, мы больше не видим таких высоких цифр, потому что это еще больше увеличивает нагрузку на удаленные серверы, а браузеры заботятся о защите инфраструктуры Интернета.
Это означает, что с современными браузерами труднее добиться того, чтобы сервисы, не поддерживающие активность, так же быстро реагировали, как и сервисы поддержки активности. Кроме того, некоторые браузеры (например, Opera) используют эвристику, чтобы попытаться использовать конвейерную обработку. Конвейерная обработка - это эффективный способ использования проверки активности, поскольку он почти устраняет задержку, отправляя несколько запросов, не дожидаясь ответа. Я пробовал это на странице со 100 маленькими фотографиями, и первый доступ примерно в два раза быстрее, чем без сохранения активности, но следующий доступ примерно в 8 раз быстрее, потому что ответы настолько малы, что учитывается только задержка (только «304» отклика).
Я бы сказал, что в идеале у нас должны быть некоторые настройки в браузерах, чтобы они поддерживали связь между извлеченными объектами и немедленно отбрасывали их, когда страница была завершена. Но, к сожалению, мы этого не видим.
По этой причине некоторые сайты, которым необходимо установить серверы общего назначения, такие как Apache, на передней стороне и которые должны поддерживать большое количество клиентов, обычно должны отключать поддержку активности. И чтобы заставить браузеры увеличивать количество подключений, они используют несколько доменных имен, чтобы загрузки можно было распараллеливать. Это особенно проблематично на сайтах, интенсивно использующих SSL, потому что настройка соединения еще выше, так как есть еще один дополнительный круговой обход.
В настоящее время чаще всего наблюдается то, что такие сайты предпочитают устанавливать легкие внешние интерфейсы, такие как haproxy или nginx, которые без проблем обрабатывают от десятков до сотен тысяч одновременных подключений, они включают поддержку активности на стороне клиента и отключают его на стороне клиента. Сторона Apache. С этой стороны, стоимость установления соединения практически равна нулю с точки зрения ЦП и совсем не заметна с точки зрения времени. Таким образом, это обеспечивает лучшее из обоих миров: низкую задержку из-за поддержания активности с очень маленькими таймаутами на стороне клиента и небольшое количество подключений на стороне сервера. Все счастливы :-)
Некоторые коммерческие продукты еще больше улучшают это, повторно используя соединения между передним балансировщиком нагрузки и сервером и мультиплексируя все клиентские соединения через них. Когда серверы расположены близко к LB, выигрыш не намного выше, чем у предыдущего решения, но часто требуется адаптация приложения, чтобы гарантировать отсутствие риска пересечения сеанса между пользователями из-за неожиданного разделения соединения между несколькими пользователями. . Теоретически этого не должно происходить. Реальность сильно отличается :-)
источник
За годы, прошедшие с тех пор, как это было написано (и размещено здесь, в stackoverflow), у нас теперь есть серверы, такие как nginx, популярность которых растет.
Например, nginx может поддерживать 10 000 активных соединений в одном процессе, имея всего 2,5 МБ (мегабайта) ОЗУ. На самом деле легко держать открытыми несколько тысяч соединений с очень небольшим объемом оперативной памяти, и единственными ограничениями, которые вы столкнетесь, будут другие ограничения, такие как количество дескрипторов открытых файлов или TCP-соединений.
Сохранение активности было проблемой не из-за каких-либо проблем со спецификацией keep-alive, а из-за модели масштабирования Apache, основанной на процессах, и из-за того, что keep-alive были взломаны на сервере, архитектура которого не была разработана для этого.
Особенно проблематичен Apache Prefork + mod_php + keep-alives. Это модель, в которой каждое отдельное соединение будет продолжать занимать всю оперативную память, которую занимает процесс PHP, даже если он полностью простаивает и остается открытым только для поддержания активности. Это не масштабируется. Но серверы не обязательно должны быть спроектированы таким образом - нет особой причины, по которой серверу нужно поддерживать каждое поддерживающее соединение в отдельном процессе (особенно, когда каждый такой процесс имеет полный интерпретатор PHP). PHP-FPM и модель обработки сервера на основе событий, такая как в nginx, элегантно решают проблему.
Обновление 2015:
SPDY и HTTP / 2 заменяют функцию поддержки активности HTTP чем-то еще лучшим: возможностью не только поддерживать соединение и делать несколько запросов и ответов по нему, но и мультиплексировать их, чтобы ответы можно было отправлять в любом порядке , и параллельно, а не только в том порядке, в котором они были запрошены. Это предотвращает блокировку медленных ответов более быстрых и устраняет соблазн браузеров поддерживать несколько параллельных подключений к одному серверу. Эти технологии дополнительно подчеркивают недостатки подхода mod_php и преимущества чего-то вроде событийного (или, по крайней мере, многопоточного) веб-сервера, соединенного отдельно с чем-то вроде PHP-FPM.
источник
Насколько я понимаю, это мало связано с процессором, а связано с задержкой при открытии повторяющихся сокетов на другой конец света. даже если у вас бесконечная пропускная способность, задержка подключения замедлит весь процесс. усиливается, если на вашей странице десятки объектов. даже постоянное соединение имеет задержку запроса / ответа, но она уменьшается, когда у вас есть 2 сокета, так как в среднем один должен передавать данные, а другой может блокировать. Кроме того, маршрутизатор никогда не предполагает, что сокет подключается, прежде чем разрешить вам писать в него. Требуется полное рукопожатие туда и обратно. опять же, я не претендую на звание эксперта, но я всегда так видел. что было бы действительно круто, так это протокол полностью ASYNC (нет, не полностью больной протокол).
источник
Очень длительные проверки активности могут быть полезны, если вы используете CDN с «исходным запросом», например CloudFront или CloudFlare. Фактически, это может сработать быстрее, чем отсутствие CDN, даже если вы обслуживаете полностью динамический контент.
Если вы долго поддерживаете активность, так что каждый PoP в основном имеет постоянное соединение с вашим сервером, то при первом посещении вашего сайта пользователи могут выполнить быстрое установление связи TCP со своим локальным PoP вместо медленного рукопожатия с вами. (Самому свету требуется около 100 мс, чтобы пройти половину земного шара по оптоволокну, а для установления TCP-соединения требуется передача трех пакетов туда и обратно. SSL требует трех циклов приема -передачи .)
источник