Connection
Заголовок Connection определяет, остаётся ли сетевое соединение активным после завершения текущей транзакции (запроса). Если в запросе отправлено значение keep-alive , то соединение остаётся и не завершается, позволяя выполнять последующие запросы на тот же сервер.
Предупреждение: Заголовки, связанные с соединением, такие как Connection и Keep-Alive (en-US) , запрещены в HTTP/2. Chrome и Firefox просто игнорируют эти заголовки в HTTP/2 ответах, однако Safari, следуя требованиям HTTP/2, вообще не будет загружать какие-либо ответы, которые содержат данные заголовки.
За исключением стандартных заголовков «hop-by-hop» ( Keep-Alive (en-US) , Transfer-Encoding (en-US) , TE (en-US) , Connection , Trailer (en-US) , Upgrade (en-US) , Proxy-Authorization (en-US) и Proxy-Authenticate (en-US) ), любые «hop-by-hop» заголовки, используемые в сообщении, должны быть перечислены в заголовке Connection так, чтобы первый прокси знал, как их использовать, и не передавал дальше. Также могут быть перечислены стандартные «hop-by-hop» заголовки (часто это относится к Keep-Alive (en-US) , но это необязательно).
Тип заголовка | Общий заголовок |
---|---|
Запрещённое имя заголовка | да |
Синтаксис
Connection: keep-alive Connection: close
Указания
Указывает, что клиент или сервер хотели бы закрыть соединение. Это значение по умолчанию для запросов HTTP/1.0.
Указывает, что клиент хотел бы сохранить соединение активным. Постоянное соединение используется по умолчанию для запросов HTTP/1.1. Список заголовков — это имена заголовка, которые удаляются первым непрозрачным прокси-сервером или промежуточным кешем: эти заголовки определяют соединение между источником и первым объектом, а не целевым узлом.
Совместимость браузеров
BCD tables only load in the browser
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 3 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Что такое конекшены с сервером, как работают, зачем нужны и как использовать?
Начнем с того, что это TCP, идем в вики Механизм TCP предоставляет поток данных с предварительной установкой соединения , то есть любой запрос на любой сайт — это первым делом подключение к нему, а уже потом манипуляция пакетами. Подключение, это весьма дорогая операция, занимающая прилично так времени. Ну вот и придумали «постоянное соединение», которое использует одно соединение клиент<>сервер для взаимодействия с пакетами. Это кстати одна из причин, почему не стоит постоянно создавать HttpClient , вот гляньте просто этот код, что видите?
11 окт 2021 в 22:46
Сейчас все соединения по умолчанию постоянные, они закрываются автоматически по истечению таймера OS, либо по запросу клиента. Если мне память не изменяет, то за этим следит сама OS (можете, к примеру глянуть в Windows все соединения, прописав в консоль netstat ). Код выше посмотрели? Что увидели? Верно, в первом случае мы постоянно создаем новый клиент с новым соединением, а как я писал выше — соединение, дорогостоящая операция, что в итоге нам дало 200+мс время ожидания каждого запроса, а вот если соединение одно, то первый ~200, остальные в два раза меньше (код советую запускать у себя!).
11 окт 2021 в 22:53
Evgeniy, что за соединения вы дали ответ (это ТСP соединения), спасибо! Теоретически понятно в чем выгода, не нужно будет часть действий каждый раз осуществлять. Хотя код не очень стабильно время выдает и сложно трактовать его результаты. netstat — дал список, можно изучать 🙂
11 окт 2021 в 23:01
А вот OS как я понял следит, но не вмешиваеться пока все хорошо веб сервера разруливают. Хотя, Вы писали про таймеры, нужно смотреть.
11 окт 2021 в 23:06
не очень стабильно — это проблемы онлайн компилятора, запустите у себя, вбейте любой адрес, укажите любое число, и смотрите результат (у меня постоянно такой. netstat — дал список — отсортируйте там по адресу (прим: netstat -n | select-string -pattern «111.111.111.111» ) и последите за жизнью запросов. OS как я понял следит — да, даже если вы сами напишете .Dispose() или аналогичное, то запрос будет еще висеть на уровне OS со статусом TIME_WAIT некое время (настройка OS). Сам же коннект, если долго не используется — закрывается по таймауту.
11 окт 2021 в 23:24
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Все очень просто.
Каждый раз, когда браузер «отрисовывает» страницу, это порождает «шквал» запросов на множество серверов. Потому что страница устроена очень сложно: это довольно много js-кода и десятки картинок с разных серверов.
Плюс к этому, этот js код начинает ajax-ом стучаться в разные методы бэкэнда.
Причем, по хорошему это должно идти не по http, а по https.
А теперь вспомним, что такое https. Это значит, что при устновлении каждого tcp-соединения происходит обмен открытыми ключами для создания зашифрованного канала — ssl handshaking.
И просто в HTTP 1.1 можно провести этот обмен ключами один раз между клиентом и конкретным сервером, а потом пользоваться уже установленным tcp соединением, не начиная всю эту возню с ключами заново при следующем обращении к тому же самому серверу.
Этот процесс абсолютно прозрачен как для сервера, так и для клиента. Более того, во многих случаях этот tcp-коннекшн существует между клиентом и энджинксом, который стоит «на входе» и служит системой распределения нагрузки, а сам nginx уже раскидывает запросы по целой ферме серверов для обслуживания бэкэнд-запросов, которые прячутся за ним.
Откровенно говоря, я не знаю, кто отправляет заголовок Connection: close. tcp соединения имеют свойство «протухать» — ну, перешли вы через дорогу, сотовый телефон подключился к другой вышке, а трансляция потоковой музыки через спотифай продолжается. Просто на более низком уровне, чем логика клиента, tcp коннекшн порвался и установился заново, когда понадобилось протащить с сервера следующий кусочек музкального потока.
В Вашем вопросе собрано несколько вопросов, если у Вас остались сомнения по поводу тех вопросов, на которые я не ответил — уточните исходный вопрос, подумаем еще.
Кстати, только что в голову пришел простой и любопытный эксперимент. Сделем простую страницу на сервере, поддерживающем http 1.1. Посмотрим на статистику открытых соединений на клиенте — ну,там, при помощи ss или более олдскульно — через netstat. Теперь откроем страницу в браузере.
Если я прав — то после полной загрузки страницы, когда уже всё прогрузилось и браузер ничего не ждёт, должны остаться одно или несколько открытых tcp-соединений с сервером, откуда была загружена страница. Это как раз позволило бы, если бы клиент захотел что то еще загрузить, воспользоваться уже открытым коннектом.
Если же мои представления не верны — я буду рад, если кто то меня поправит 🙂 — о, пока я писал ответ, в коментариях к вопросу сказали всё то же самое , только короче!
Постоянное HTTP-соединение
Постоянное HTTP-соединение (англ. HTTP persistent connection , также называемые HTTP keep-alive или повторное использование соединений HTTP) — использование одного TCP-соединения для отправки и получения множественных HTTP-запросов и ответов вместо открытия нового соединения для каждой пары запрос-ответ.
Функционал
При работе по протоколу HTTP 1.0 с подобным типом соединений нет официальной спецификации. По сути, это дополнение к существующему протоколу. Если браузер посылает команду keep-alive, то он дополняет заголовок запроса следующим:
Connection: Keep-Alive
Затем, когда сервер получает такой запрос и генерирует ответ, то он также добавляет в заголовок ответа
Connection: Keep-Alive
После этого соединение не разрывается, а остаётся открытым. Когда клиент отправляет ещё один запрос, то он использует это же соединение. Так будет продолжаться до тех пор, пока клиент или сервер не решат, что обмен окончен, и одна из сторон завершает соединение.
При работе по HTTP 1.1 все соединения считаются постоянными, если не обозначено иное. [1] При этом постоянные соединения не используют сообщения keepalive, а просто позволяют передачу множественных запросов в одном и том же соединении. Тем не менее, время ожидания по умолчанию в httpd для Apache 2.0 [2] составляет всего 15 секунд, а для Apache 2.2 лишь 5 секунд. [3] Преимуществом короткого таймаута является возможность быстрее передать клиенту множественным соединением несколько компонентов веб-страницы, а не более долгим методом инициации нескольких серверных процессов или потоков. [4]
Примечания
- ↑Persistent HTTP Connections in RFC 2616 «Hypertext Transfer Protocol — HTTP/1.1»
- ↑Apache HTTP Server — KeepAlive Directive
- ↑Apache HTTP Server 2.2 — KeepAliveTimeout Directive
- ↑Multiple (wiki)Httpd/KeepAlive. Docforge. Архивировано из первоисточника 31 октября 2012.Проверено 30 января 2010.
Ссылки
- RFC 2616 (HTTP/1.1), 8.1 Persistent Connections
- Persistent Connection Behavior of Popular Browsers (dated)
- Apache Keep-Alive Support
- Network Performance Effects of HTTP/1.1, CSS1, and PNG
- Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное.
- Дополнить статью (статья слишком короткая либо содержит лишь словарное определение).
- Протокол HTTP
Использование KEEPALIVE-сокетов для обнаружения и отключения зависших клиентских соединений InterBase и Firebird
В системах, предназначенных для работы в реальном времени или близком к нему, существует проблема отслеживания на серверной стороне состояния клиентских соединений и принятия мер для их принудительного отключения в случае недоступности клиента вследствие разрыва соединения. Особенно при использовании Classic Firebird SQL Server важно своевременно освобождать ресурсы, занимаемые такими фантомными соединениями.
Если имеются пользователи, подключающиеся к серверу через модемы, то достаточно велика вероятность обрыва модемного соединения в самый неподходящий момент.
Например, клиент сохраняет измененный набор записей. После выполнения UPDATE, но до выполнения COMMIT модемное соединение разрывается. Обычно клиентское приложение в такой ситуации восстанавливает соединение с сервером, но клиент, продолжая работу с теми же данными, при сохранении которых он получил сообщение об ошибке по причине разрыва соединения, не может сохранить свои изменения, получая со стороны сервера сообщение о конфликте блокировки. Ему мешает его предыдущее соединение, открывшее транзакцию, в контексте которой был выполнен UPDATE, но не был выполнен COMMIT, т. к. соединение со стороны клиента было разорвано.
Точно так же обрывы соединений могут возникать и в локальной сети, если сбоит оборудование – сетевые карты, хабы, коммутаторы – или возникают помехи. В interbase.log/firebird.log обрывы коннектов tcp показываются как ошибки 10054 (Windows. на Unix – 104), обрывы netbeui – как ошибки 108/109.
Для отслеживания и отключения таких «мертвых» соединений InterBase и Firebird использует один из двух механизмов – DUMMY-пакеты (реализован на прикладном уровне начиная с InterBase 5.0 между сервером InterBase/ Firebird и клиентской библиотекой gds32/fbclient, включается в ibconfig/firebird.conf и в данном документе рассматриваться не будет) и KEEPALIVE-сокеты (используется по умолчанию начиная с InterBase 6.0). Использование KEEPALIVE включается установкой опции сокета SO_ KEEPALIVE при его открытии. Вам не нужно специально заботиться об этом, если вы используете Firebird 1.5 или выше – это реализовано в программном коде сервера Firebird, как для Classic, так и для Superserver. Для InterBase и Firebird (младше 1.5) в варианте Classic (существуют только для Unix/ Linux) необходима дополнительная настройка (см. п. 3). В этом случае отслеживание состояния соединения возлагается не на сервер Firebird, а на стек TCP операционной системы. Однако для практического использования требуется настройка параметров KEEPALIVE.
Примечание. Как показывает практика, устойчивость работы механизма dummy-пакетов, реализованная еще в InterBase 5.0 и неоднократно исправленная в Firebird 1.5. x сильно зависит от операционных систем клиента и сервера, версий стека tcp и множества других условий. То есть, эффективность такой системы в реальной сети стремится к нулю. Ко всему прочему, в Borland Developer Network упоминалось, что для Windows существует проблема с утечкой памяти в adf.sys при использовании dummy-пакетов. Именно поэтому необходимо настраивать механизм KEEPALIVE, за который отвечает стек tcp клиента и сервера.
Описание KEEPALIVE
Поведение KEEPALIVE-сокетов регулируется параметрами, представленными в таблице:
Параметр | Описание |
---|---|
KEEPALIVE_ TIME | Интервал времени, по истечении которого начинаются пробы KEEPALIVE |
KEEPALIVE_INTERVAL | Интервал времени между пробами KEEPALIVE |
KEEPALIVE_PROBES | Количество проб KEEPALIVE |
Стек TCP отслеживает момент прекращения прохождения пакетов между клиентом и сервером, запуская таймер KEEPALIVE. Как только таймер достигнет величины KEEPALIVE_ TIME, стек TCP сервера выполняет первую пробу KEEPALIVE. Проба – это пустой пакет c флагом ACK, отправляемый клиенту. Если на стороне клиента все в порядке, то стек TCP на клиентской стороне посылает ответный пакет с флагом ACK и стек TCP сервера, получив ответ, сбрасывает таймер KEEPALIVE. Если клиент не отвечает на пробу, то пробы со стороны сервера продолжают выполняться. Их количество равно KEEPALIVE_ PROBES и выполняются они через интервал времени KEEPALIVE_ INTERVAL. Если клиент не ответил на последнюю пробу, то по истечении еще одного интервала времени KEEPALIVE_ INTERVAL стек TCP операционной системы сервера закрывает соединение и Firebird высвобождает все ресурсы, занимаемые обслуживанием данного соединения.
Таким образом, разорванное клиентское соединение будет закрыто по истечении времени KEEPALIVE_ TIME+ ( KEEPALIVE_ PROBES+1)* KEEPALIVE_ INTERVAL.
Значения параметров по умолчанию достаточно велики, что делает их практическое применение неэффективным. Параметр KEEPALIVE_ TIME, например, имеет значение по умолчанию 2 часа и в Linux и в Windows. Реально достаточно одной-двух минут для принятия решения о принудительном отключении недоступного клиента. С другой стороны, настройки KEEPALIVE по умолчанию иногда приводят к принудительному обрыву соединений в сетях Windows, которые неактивны в течение этих самых двух часов (сомнения по поводу необходимости наличия в приложениях таких соединений – это уже другой вопрос).
Ниже мы рассмотрим настройку этих параметров для операционных систем семейства Windows и операционной системы Linux.
Настройка KEEPAILVE в Linux
Параметры KEEPALIVE в Linux можно изменить либо прямым редактированием файловой системы / proc либо вызовами sysctl.
Для первого случая надо редактировать:
/proc/sys/net/ipv4/tcp_keepalive_time
/proc/sys/net/ipv4/tcp_keepalive_intvl
/proc/sys/net/ipv4/tcp_keepalive_probes
Для второго случая выполнить команды:
sysctl –w net.ipv4.tcp_keepalive_time=value
sysctl –w net.ipv4.tcp_keepalive_intvl=value
sysctl –w net.ipv4.tcp_keepalive_probes=value
Время задается в секундах.
Для автоматической установки этих параметров в случае перезагрузки сервера добавьте в /etc/sysctl.conf:
net.ipv4.tcp_keepalive_intvl = value
net.ipv4.tcp_keepalive_time = value
net.ipv4.tcp_keepalive_probes = value
Слово замените на нужные вам величины.
Если вы используете Firebird Classic ранее версии 1.5, то в /etc/xinet.d/firebird пропишите следующее:
FLAGS=REUSE KEEPALIVE
Настройка KEEPALIVE в Windows 95/98/ME
Ветка реестра:
HKEY_ LOCAL_ MACHINE\System\CurrentControlSet\Services\VxD\MSTCP
- KeepAliveTime = миллисекунды
Тип: DWORD
Для Windows 98, тип STRING.
Определяет время неактивности соединения в миллисекундах по истечении которого начинаются KEEPALIVE-пробы. Значение по умолчанию – 2 часа (7200000).
- KeepAliveInterval = 32-значное число
Тип: DWORD
Для Windows 98, тип STRING.
Определяет время в миллисекундах между повторами KEEPALIVE-проб. Как только истек интервал KeepAliveTime через каждый интервал времени KeepAliveInterval (в миллисекундах) посылаются KEEPALIVE-пробы максимальным количеством MaxDataRetries. Если ответ не придет, соединение закрывается. Значение по умолчанию 1 секунда (1000).
- MaxDataRetries = 32-значное число
Тип: STRING
Определяет максимальное количество KEEPALIVE-проб. Значение по умолчанию 5.
Настройка KEEPALIVE в Windows 2000/NT/XP
Ветка реестра:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\.
- 2000/NT: http://support.microsoft.com/kb/120642/en-us
- XP: http://support.microsoft.com/kb/314053
Настройка KEEPALIVE в Windows (для клиентов)
Данная настройка необязательна, но, возможно, позволит уменьшить количество сообщений о потере соединения при использовании ненадежных линий связи. Добавьте в ветку реестра
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
параметр DisableDHCPMediaSense=1. См. описание данного параметра здесь: http://support.microsoft.com/?scid =kb%3Bru%3B239924&x=13&y=14.
- Убедимся, что в firebird.conf отключен механизм DUMMY-пакетов (параметр закомментирован)
.
#DummyPacketInterval=0
.
- Убедимся в наличии конфигурационного файла /etc/xinet.d/firebird
В нем все оставляем по умолчанию, как прописано при установке. Ничего добавлять не надо.
- Изменяем параметры стека TCP
sysctl –w net.ipv4.tcp_keepalive_time = 15
sysctl –w net.ipv4.tcp_keepalive_intvl = 10
sysctl –w net.ipv4.tcp_keepalive_probes = 5
- Устанавливаем соединение к любой базе данных на сервере с любого сетевого клиента.
- Смотрим трафик на сервере используя любой фильтр пакетов.
При указанной конфигурации параметров /proc/sys/net/tcp_ keepalive_* через 15 секунд с момента наступления тишины в канале сервером выполняется проба. Если клиент жив, то серверу высылается ответный пакет. Еще через 15 секунд проверка повторяется и т. д.
- Если клиента отключить физически (выключить коммутатор или модем – мало ли, что может случиться в действительности), то на пробу сервера ответ от клиента не приходит, и сервер начинает с 10-ти секундным интервалом посылать пробы. Если на пятую пробу клиент не ответил, то еще через 10 секунд серверный процесс выгружается, освобождая ресурсы и блокировки. Если клиент подал признаки жизни и откликнулся хотя бы и на пятую пробу (худший случай), то снова выдерживается 15-сек тайм-аут и опять начинаются пробы. И т. д.
Заключение
В заключение хотелось бы привести практические рекомендации по выбору величин параметров KEEPALIVE.
Во-первых, определите для себя необходимую величину параметра KEEPALIVE_TIME. Чем больше будет его значение, тем позже начнутся KEEPALIVE-пробы. Если вы постоянно наблюдаете на своем сервере множество зависших коннектов, и вам приходится их удалять вручную, то следует уменьшить величину KEEPALIVE_TIME.
Во-вторых, значения параметров KEEPALIVE_INTERVAL и KEEPALIVE_PROBES должны удовлетворять вашим требованиям по своевременному отключению уже обнаруженных системой зависших соединений. Если ваши пользователи устанавливают соединения с сервером через ненадежные каналы связи, то вам, возможно, захочется увеличить количество проб и интервал между ними для того, чтобы пользователь успел обнаружить обрыв и восстановить соединение с сервером. В случае, если клиентоы используют выделенное подключение к сетям общего пользования (Интернет) или используют доступ к SQL-серверу по локальной сети, возможно уменьшение количества и интервала между KEEPALIVE-пробами.
Общие рекомендации могут звучать так: если вы на практике получаете большое количество сообщений от клиентов об ошибках сохранения результатов работы по причине конфликта блокировки без видимых на то причин, т. е. при отсутствии конкурирующих соединений, работающих с теми же данными, то вам надо увеличивать реакцию системы на отключение зависших коннектов. Практически величина KEEPALIVE_TIME может составлять от 1 минуты и более – вы сами должны оценить время выполнения самой длительной транзакции в системе, чтобы не перегружать сетевой трафик KEEPALIVE-проверками нормально работающих соединений, запустивших длительные транзакции. Величина KEEPALIVE_INTERVAL – от 10 секунд и более, а величина KEEPALIVE_PROBES – от 5 проверок и более. Помните, что большое количество проверок и малый интервал между ними могут существенно увеличить сетевой трафик при большом количестве одновременно работающих пользователей.
Также помните, что в случае, если ваши пользователи активно работают по изменению общих данных, ошибки блокировки будут возникать как следствие штатной ситуации. В этом случае вам потребуетсякак корректная обработка ошибок блокировки в клиентских приложениях и само приложение должно быть спроектировано так, чтобы минимизировать появление таких ошибок.
- Клиенты используют модемные соединения, в системе преобладают короткие транзакции, время простоя ограничено 3 минутами.
KEEPALIVE_TIME 1 минута
KEEPALIVE_PROBES 3
KEEPALIVE_INTERVAL 30 секунд
ИТОГО 3 минуты
- Клиенты используют доступ по локальной сети, в системе преобладают короткие транзакции, время простоя ограничено 2 минутами.
KEEPALIVE_TIME 30 сек
KEEPALIVE_PROBES 5
KEEPALIVE_INTERVAL 10 сек
ИТОГО 90 секунд
- Клиенты используют любые соединения, время простоя не регламентируется.
KEEPALIVE_TIME 15 мин
KEEPALIVE_PROBES 4
KEEPALIVE_INTERVAL 1 мин
ИТОГО 20 минут
- Клиенты используют любые соединения, в системе возможны длительные транзакции, время простоя ограничено 15 минутами.
KEEPALIVE_TIME 12 мин
KEEPALIVE_PROBES 7
KEEPALIVE_INTERVAL 15 сек
ИТОГО 14 минут
Надеемся, приведенных примеров будет достаточно для правильной настройки механизма KEEPALIVE стека TCP.