tcp keep alive что это

Определение разрыва TCP-соединения


Автор: Андрей Елсуков
Источник: RSDN Magazine #1-2004

Опубликовано: 03.10.2004
Исправлено: 10.12.2016
Версия текста: 1.0

Введение

Протокол TCP, в отличие от UDP, осуществляет доставку дейтаграмм, называемых сегментами, в виде байтовых потоков с установлением соединения. TCP применяется в тех случаях, когда требуется гарантированная доставка сообщений. Он использует контрольные суммы пакетов для проверки их целостности, контролирует последовательность передаваемых данных и избавляет программиста от многих рутинных задач. В качестве примеров прикладных протоколов, использующих TCP, можно назвать протокол FTP, HTTP, SMTP и многие другие.

ПРИМЕЧАНИЕ

В данной статье речь будет идти о реализациях стека TCP/IP в Microsoft Windows NT/2000/XP и более поздних версиях, а также реализации Windows Sockets версии 2 и более поздних.

Таймер keep-alive

Принцип работы этого таймера предельно прост. Если канал между клиентом и сервером пассивен некоторое время (по умолчанию 2 часа), то посылается служебное сообщение, если ответа на него не поступило, через 75 секунд (обычно) сообщение посылается повторно и так несколько раз. Если ответ получен – таймер сбрасывается, и отчёт начинается заново. Если после нескольких повторов ответа так и не поступило, то соединение разрывается. Число повторов зависит от реализации стека TCP/IP, в некоторых реализациях может изменяться, в некоторых – нет…

При использовании сокетов в Windows keep-alive сообщения по умолчанию выключены. Включить их можно с помощью функции setsockopt :

В качестве параметров в функцию передаются:

Для включения/выключения посылки keep-alive используется опция SO_KEEPALIVE уровня SOL_SOCKET. Параметр optval интерпретируется функцией как булево значение, для включения посылки он должен иметь значение TRUE, иначе – FALSE.

На практике нет никакого смысла ждать 2 часа до посылки keep-alive сообщения, куда интереснее более реальные интервалы времени (несколько десятков секунд или минут). Для изменения этого интервала в Winsock2 предусмотрена функция WSAIoctl :

В качестве параметров в функцию передаются:

Заключение

Для проверки работы keep-alive я написал простенькую программку, которая соединяется с 21-м портом по заданному адресу. Интервал посылки keep-alive сообщений устанавливается равным 10 секундам, с повтором через 1 секунду. Далее я пользовался анализатором трафика и пакетным фильтром. С помощью пакетного фильтра создал ситуацию потери связи с сервером, в результате которой после нескольких безответных посылок keep-alive возникает событие FD_CLOSE.

Исходник проекта (MSVC 7.0) прилагается в архиве.

Источник

Имеет ли TCP-сокет соединение «keep alive»?

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

6 ответов

TCP сокеты остаются открытыми, пока они не будут закрыты.

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

теперь это соединение сокета останется открытым навсегда или есть ограничение времени ожидания, связанное с ним, подобное HTTP keep-alive?

короткий ответ:да, есть тайм-аут, и он применяется через TCP Keep-Alive.

если вы хотите настроить таймаут Keep-Alive, см. раздел «изменение таймаутов TCP» ниже.

введение

TCP-соединения состоят из двух розеток, одна на каждом конце соединения. Когда одна сторона хочет прекратить соединение, она отправляет RST пакет, который другая сторона признает, и оба закрывают свои сокеты.

Keep-Alive Process

есть три настраиваемых свойства, которые определяют, как Keep-Alives работают. В Linux они 1 :

процесс работает следующим образом:

этот процесс включен по умолчанию в большинстве операционных систем, и поэтому мертвые TCP-соединения регулярно обрезаются, как только другой конец не отвечает в течение 2 часов 11 минут (7200 секунд + 75 * 9 секунд).

Gotchas

2 Часа По Умолчанию

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

Keep-Alive является необязательным

по данным RFC 1122 4.2.3.6, отвечая на и/или ретрансляцию TCP Keep-Alive пакеты необязательно:

разработчики могут включать «keep-alives» в свои реализации TCP, хотя эта практика не является общепринятой. Если keep-alives в комплекте, приложение должно быть в состоянии включить или выключить их для каждого TCP-соединение, и они должны по умолчанию отключены.

крайне важно помнить, что сегменты ACK, не содержащие данных, не являются надежно передается по протоколу TCP.

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

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

изменение таймаутов TCP

За Исполнение

вместо этого, вы можете быть вынуждены применить конфигурацию операционной системы в целом. Имейте в виду, что эта конфигурация повлияет на все TCP-соединения, запущенные во всей системе.

Linux

текущие настройки TCP Keep-Alive можно найти в

вы можете обновить любой из них так:

такие изменения не будут сохраняться при перезапуске. Чтобы внести постоянные изменения, используйте sysctl :

Mac OS X

текущие настройки можно просмотреть с помощью sysctl :

обратите внимание, Mac OS X определяет keepidle и keepintvl в единицах МС в отличие от Linux, который использует секунды.

свойства можно задать с помощью sysctl который сохранит эти настройки при перезагрузке:

кроме того, вы можете добавлять их в /etc/sysctl.conf (создает файл, если он не существует).

Windows

у меня нет машины Windows для подтверждения, но вы должны найти соответствующие настройки TCP Keep-Alive в реестре at

1. См. man tcp для получения дополнительной информации.

2. Этот пакет часто называют пакетом» Keep-Alive», но в спецификации TCP это просто обычный ACK пакета. Такие приложения, как Wireshark, могут маркировать его как пакет» Keep-Alive » путем метаанализа последовательности и номеров подтверждения, которые он содержит в ссылка на предыдущие сообщения в сокете.

вы ищете опцию сокета SO_KEEPALIVE.

на API сокета Java предоставляет» keep-alive » для приложений через setKeepAlive и getKeepAlive методы.

EDIT: SO_KEEPALIVE реализован в стеках сетевых протоколов ОС без отправки каких-либо» реальных » данных. Интервал keep-alive зависит от операционной системы и может быть настроен через параметр ядра.

поскольку данные не отправляются, SO_KEEPALIVE может только проверить живучесть сетевое подключение, а не живость службы, к которой подключен сокет. Чтобы проверить последнее, вам нужно реализовать то, что включает отправку сообщений на сервер и получение ответа.

Это из спецификации TCP,

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

Как вы можете видеть, интервал TCP keepalive по умолчанию слишком длинный для большинства приложений. Возможно, вам придется добавить активности в свой протокол.

Если вы находитесь за маскирующимся NAT (как и большинство домашних пользователей в эти дни), существует ограниченный пул внешних портов, и они должны быть разделены между TCP-соединениями. Поэтому маскирующиеся NATs склонны предполагать, что соединение было прервано, если данные не были отправлены в течение определенного периода времени.

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

использование keepalives оба уменьшается вероятность того, что соединение будет прервано где-то по линии, а также позволяет узнать о сломанном соединении раньше.

вот некоторая дополнительная литература по keepalive, которая объясняет это гораздо более подробно.

поскольку Java не позволяет вам контролировать фактическое время keepalive, вы можете использовать примеры для их изменения, если вы используете ядро Linux (или ОС на основе proc).

Источник

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

Что такое 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 в разных ситуациях в разных браузерах.

Источник

Использование KEEPALIVE-сокетов для обнаружения и отключения зависших клиентских соединений InterBase и Firebird

Овчинников Василий, 17.05.2005, изменено – 06.09.2005.

Введение

В системах, предназначенных для работы в реальном времени или близком к нему, существует проблема отслеживания на серверной стороне состояния клиентских соединений и принятия мер для их принудительного отключения в случае недоступности клиента вследствие разрыва соединения. Особенно при использовании 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.

Описание 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.

Для первого случая надо редактировать:

Время задается в секундах.

Для автоматической установки этих параметров в случае перезагрузки сервера добавьте в /etc/sysctl.conf:

Слово замените на нужные вам величины.

Если вы используете Firebird Classic ранее версии 1.5, то в /etc/xinet.d/firebird пропишите следующее:

Настройка KEEPALIVE в Windows 95/98/ME

Настройка KEEPALIVE в Windows 2000/NT/XP

Настройка KEEPALIVE в Windows (для клиентов)

параметр DisableDHCPMediaSense=1. См. описание данного параметра здесь: http://support.microsoft.com/?scid =kb%3Bru%3B239924&x=13&y=14.

Заключение

В заключение хотелось бы привести практические рекомендации по выбору величин параметров KEEPALIVE.

Во-первых, определите для себя необходимую величину параметра KEEPALIVE_TIME. Чем больше будет его значение, тем позже начнутся KEEPALIVE-пробы. Если вы постоянно наблюдаете на своем сервере множество зависших коннектов, и вам приходится их удалять вручную, то следует уменьшить величину KEEPALIVE_TIME.

Во-вторых, значения параметров KEEPALIVE_INTERVAL и KEEPALIVE_PROBES должны удовлетворять вашим требованиям по своевременному отключению уже обнаруженных системой зависших соединений. Если ваши пользователи устанавливают соединения с сервером через ненадежные каналы связи, то вам, возможно, захочется увеличить количество проб и интервал между ними для того, чтобы пользователь успел обнаружить обрыв и восстановить соединение с сервером. В случае, если клиентоы используют выделенное подключение к сетям общего пользования (Интернет) или используют доступ к SQL-серверу по локальной сети, возможно уменьшение количества и интервала между KEEPALIVE-пробами.

Общие рекомендации могут звучать так: если вы на практике получаете большое количество сообщений от клиентов об ошибках сохранения результатов работы по причине конфликта блокировки без видимых на то причин, т. е. при отсутствии конкурирующих соединений, работающих с теми же данными, то вам надо увеличивать реакцию системы на отключение зависших коннектов. Практически величина KEEPALIVE_TIME может составлять от 1 минуты и более – вы сами должны оценить время выполнения самой длительной транзакции в системе, чтобы не перегружать сетевой трафик KEEPALIVE-проверками нормально работающих соединений, запустивших длительные транзакции. Величина KEEPALIVE_INTERVAL – от 10 секунд и более, а величина KEEPALIVE_PROBES – от 5 проверок и более. Помните, что большое количество проверок и малый интервал между ними могут существенно увеличить сетевой трафик при большом количестве одновременно работающих пользователей.

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

Источник

Преодоление разрыва удаленного соединения при отсутствии действий пользователя

При работе с GUI и терминальными приложениями нередко случается, что пользователь, работая в режиме удаленного доступа (как правило, через Интернет), покинув компьютер минут на 15, по возвращении обнаруживает, что программа зависла. На любое действие она отвечает ошибкой, содержащей примерно такие фразы: «Потеряна связь с сервером», «[WINSOCK] virtual circuit reset by host» и т.п. Наблюдается такое и при выполнении «долгоиграющих» методов (запросов к серверу), в которых не предусмотрен вывод прогресс-бара или какая-либо интерактивность.

Данная проблема характерна не только для GUI и терминальных решений на базе СУБД Caché и Ensemble компании InterSystems, а вообще для любого клиент-серверного взаимодействия по протоколу TCP/IP. Обычно она решается на прикладном уровне путём периодического обмена пустыми сообщениями специального вида, предназначенными лишь для того, чтобы просигнализировать о том, что приложение «живо».

Ниже о том, как можно решать эту проблему без программирования.

Источник проблемы

Источник проблемы лежит в природе протокола TCP/IP. Как правило, источник сеанса TCP/IP и его приемник находятся в различных сетях, и на пути сеанса встречается несколько маршрутизаторов. Хотя бы один из них обычно выполняет NAT-преобразование адресов. Ресурсы маршрутизатора всегда ограничены, поэтому некоторые из них выполняют очистку NAT-таблиц от «мёртвых» сеансов. Сеанс считается «мёртвым», если по нему не передавались пакеты в течение некоторого заданного интервала времени (назовем его интервал очистки). Таким образом, «молчаливый» сеанс может быть принят за «мёртвый» и вычищен из NAT-таблицы. При этом ни источник, ни приемник об этом не уведомляются («не царское дело»), и оба они остаются в уверенности, что сеанс ещё «жив» (в чем легко убедиться командой netstat, выполнив ее на клиенте или на сервере в момент возникновения ошибки, но до нажатия на ОК). Когда пользователь, получивший сообщение об ошибке, нажмет на ОК, о разрыве сеанса узнает клиент; серверный же процесс завершится, когда «умерший» сеанс распознает ОС.

Экспериментально установлено, что интервал очистки у многих маршутизаторов (по крайней мере, с прошитым Linux 2.4/iptables) составляет около 10 минут. Постараемся заставить наш TCP-сеанс автоматически поддерживать себя в активном состоянии, даже когда не передается никаких пакетов с данными.

Предлагаемое решение

На уровне ОС обнаружением разорванных TCP-соединений управляют следующие параметры ядра, управляющие работой механизма tcp_keepalive [1]:
tcp_keepalive_time — интервал времени с момента отправки последнего пакета с данными; по истечении этого срока соединение помечается как требующее проверки; после начала проверки параметр не используется;
tcp_keepalive_intvl — интервал между проверочными пакетами (отправка которых начинается по истечении tcp_keepalive_time);
tcp_keepalive_probes — количество неподтвержденных проверочных пакетов; по исчерпании этого счетчика соединение считается разорванным.

Надо сказать, что механизм tcp_keepalive имеет двойное назначение: он может использоваться как для искусственного поддержания активности соединения, так и для выявления разорванных (так называемых «полуоткрытых») соединений. В данной статье обсуждается в основном первое применение, о втором применении, возможно, речь пойдёт в следующей статье на эту тему.

Для того чтобы механизм tcp_keepalive был задействован для TCP-соединений, необходимы два условия:
• поддержка на уровне ОС; к счастью, и в Windows, и в Linux она имеется;
• на одном из концов соединения сокет должен быть открыт с параметром SO_KEEPALIVE. Как оказалось, сервисы Caché открывают сокеты с этим параметром, а сервис OpenSSH несложно заставить поступать аналогично.

Наибольший интерес для нас представляет первый параметр (tcp_keepalive_time), так как именно от него зависит, насколько часто будет выполняться проверка неактивных (с точки зрения отсутствия трафика) соединений. Его значение по умолчанию — и в Windows, и в Linux — равно двум часам (7200 с). Типичное же время бездействия, после которого наступает разрыв, составляет около 10 минут. Поэтому предлагается установить значение параметра в 5 минут, что позволит искусственно поддерживать активность TCP-сеансов, не перегружая сеть избыточным трафиком (5 минут — это не 5 секунд).

Установка параметров tcp_keepalive на сервере Windows

Вы должны обладать правами Администратора к серверу. В разделе реестра
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
создайте параметр DWORD с именем KeepAliveTime и значением 300000 (десятичным). Параметр задаётся в миллисекундах, поэтому предлагаемое значение — это 5 минут. После чего остановите Caché и перезагрузите сервер.

Что касается двух других параметров tcp_keepalive, то их умолчания в Windows таковы:

KeepAliveInterval
Key: Tcpip\Parameters
Value Type: REG_DWORD—time in milliseconds
Valid Range: 0–0xFFFFFFFE
Default: 1000 (1 секунда)

KeepAliveProbes
Такого параметра (устанавливающего количество неподтвержденных проверочных пакетов), в реестре не существует. Согласно [2], в Windows 2000 / XP / 2003 в этом качестве используется значение параметра TcpMaxDataRetransmission (умолчание — 5), а в более поздних версиях [3] — фиксированное значение, равное 10. Поэтому, если менять только значение первого параметра (с 7200 на 300), сохраняя умолчание для второго, сервер Windows 2008 будет узнавать о разрыве TCP-соединения через 1*10 + 300 = 310 секунд.

Установка параметров tcp_keepalive на сервере Linux

Изменить значения параметров можно «на ходу», не перезагружая сервер. Зайдите как root и выполните:

Чтобы сделать изменение долговечным по отношению к возможным перезагрузкам сервера, проще всего отредактировать файл параметров ядра /etc/sysctl.conf, добавив в него строку (лучше две):

Обратите внимание, что в отличие от Windows, значение параметра задается в секундах.
Что касается остальных двух параметров tcp_keepalive, то их умолчания в Linux таковы:

Если менять только значение первого параметра (с 7200 на 300), сохраняя умолчания для остальных двух, сервер Linux будет узнавать о разрыве соединения только через 75*9 + 300 = 975 секунд.

Установка параметра TCPKeepAlive в конфигурации СУБД Caché

Начиная с версии 2008.2, в Caché для платформ Windows и Linux появилась возможность задавать tcp_keepalive_time на уровне сокета, что удобно, так как позволяет избежать изменения настроек операционной системы. Однако «в чистом виде» эта возможность, в основном, представляет интерес лишь для независимых разработчиков сокет-серверов. К счастью, она была дополнена параметром конфигурации TCPKeepAlive=n в секции [SQL], доступным для редактирования со страницы Портала управления системой: Конфигурация > Общие Настройки SQL. Значение по умолчанию — 300 секунд (то, что доктор прописал). Действие параметра распространяется не только на SQL, но и, как нетрудно догадаться, на любые соединения с Caché, обслуживаемые сервисом %Service_Bindings. К ним относится, в частности, и объектный доступ через CacheActiveX.Factory, поэтому если ваше приложение может использовать этот протокол в качестве транспорта, не стоит упускать такую возможность.

Установка параметров KeepAlive в конфигурации сервера OpenSSH

Если вы используете SSH [4] (для работы в режиме командной оболочки или как транспорт для вашего GUI-приложения), то… скорее всего, проделанной настройки ядра будет достаточно, поскольку сервис OpenSSH (по крайней мере, в версии 5.x) по-умолчанию открывает сокет с параметром SO_KEEPALIVE.

На всякий случай стоит проверить конфигурационный файл /etc/ssh/sshd_config. Найдите в нем строку

Если нашли, то делать ничего не надо, так как значения параметров по умолчанию предоставляются в закомментированном виде.

Протокол SSH v.2 имеет альтернативные средства контроля активности сеансов, например, с помощью настройки параметров сервиса OpenSSH ClientAliveInterval и ClientAliveCountMax.
При использовании этих параметров, в отличие от TCPKeepAlive, запросы KeepAlive отправляются через защищённый SSH канал и не могут быть подменены. Приходится признать, что альтернативные средства являются более безопасными, нежели традиционный механизм TCPKeepAlive, для которого существует опасность анализа KeepAlive-пакетов и организации DoS-атак [5].

Устанавливает время ожидания в секундах, по истечении которого, если не поступает информация со стороны клиента, sshd отправляет ему запрос отклика через защищённый канал. По умолчанию используется 0, что означает, что клиенту не будет направлен такой запрос.
Устанавливает количество запросов клиенту, которые могут быть отправлены sshd без получения на них отклика. Если предел достигнут, sshd разъединяется с клиентом и завершает сеанс. Значение по умолчанию: 3. Если вы установите значение параметра ClientAliveInterval равным 60, оставив ClientAliveCountMax без изменений, то не отвечающие ssh-клиенты будут отключены примерно через 180 секунд. При этом следует отключить механизм TCP KeepAlive, установив

Всегда ли это работает?

Существуют категории сетевых проблем, в которых описанный подход может быть малоэффективен.

Одна из них имеет место, когда из-за низкого качества сетевого обслуживания связь может физически пропадать в течение коротких промежутков времени. Если сеанс бездействует, а связь временно пропадает и восстанавливается до того, как клиент или сервер попытаются что-то друг другу послать, то никто из них ничего «не замечает», и TCP-сеанс сохраняется. В случае периодических проверок TCPKeepAlive возрастает вероятность обращения сервера к клиенту в моменты временного исчезновения связи, что может вести к принудительным разрывам TCP-соединения. В такой ситуации можно попробовать увеличить на сервере KeepAliveInterval до 60-75 секунд (вспомнив, что в Windows умолчание — 1 секунда) при максимальном количестве повторов равным 10, в надежде, что за 10 минут любая временная сетевая проблема самоустранится. Правда, если повторные передачи будут длиться слишком долго, и окажется, что
KeepAliveTime + (KeepAliveInterval * кол-во_повторов) > 10 минут
то TCP-сеанс, несмотря на все предпринятые усилия, может быть принят за «мёртвый» и вычищен из NAT-таблицы.

Другая категория проблем связана с недостаточной пропускной способности используемых маршрутизаторов и/или каналов связи, когда при перегрузке могут теряться любые пакеты, в том числе и KeepAlive. В случае маршрутизаторов такие проблемы иногда решаются сменой прошивки (мне, например, это помогло победить Acorp ADSL XXXX), или, в худшем случае, заменой его на более производительную модель. В случае «слишком узких» каналов связи не остаётся ничего другого, кроме как их расширять.

Заключение

Предложенный подход позволяет искусственно поддерживать активность сеансов TCP/IP, по которым в текущий момент не передается никаких данных, исключительно на системном уровне, не внося каких-либо изменений в прикладной код. На сегодня он проверен и успешно используется в Caché for UNIX (Red Hat Enterprise Linux 5 for x86-64) 2010.1.4 (Build 803), Caché for Windows (x86-64) 2010.1.4 (Build 803), а также в более поздних версиях.

Следует признать, что он эффективно работает, если сетевое соединение физически устойчиво, и кроме разрыва неактивных сеансов других сетевых проблем у вас нет.

При развёртывании приложения в агрессивной среде (удалённый доступ, распределённые системы и т.д.), подумайте о реализации KeepAlive не на уровне TCP, а на уровне защищённого протокола более высокого уровня; хорошим кандидатом здесь оказывается SSH.

Источник

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

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