Кратко
- TCP Keepalive спрашивает, отвечает ли молчащий узел на транспортном уровне; здоровье удалённого приложения он не доказывает.
- Механизм остался необязательным, настраиваемым и выключенным по умолчанию, поскольку у молчания соединения много причин.
- Один потерянный ответ не доказывает смерть, а память посредников, user timeout и энергия исключают безопасный общий интервал.
Надёжность начинается с отправленного байта
В RFC 793 обязанность TCP ясна, когда есть данные. Байты занимают последовательные позиции, подтверждения двигают передачу, пропуски вызывают повтор. В конце концов доставка удаётся, приходит reset либо срабатывает локальная политика отказа.
Простаивающее соединение не даёт такого материала. Нет нового байта, ожидающего ACK, и нет старого неподтверждённого байта, таймер которого обнаружил бы исчезнувший путь. Оба конца могут быть здоровы и намеренно молчать. Один узел мог рухнуть; маршрут, состояние межсетевого экрана или адресное отображение могли исчезнуть. Для локального TCP все эти миры выглядят одинаково тихими.
Это не дефект надёжной доставки, а предел знания о доставке, которую никто не пытался совершить.
Вопрос на шаг позади границы
RFC 1122 описал keepalive в 1989 году как спорный и необязательный механизм. Традиционная проба ставит SEG.SEQ = SND.NXT-1: непосредственно перед следующим новым байтом, доступным отправителю.
Неудобная позиция выбрана сознательно. Сегмент не должен стать новыми данными приложения, но должен побудить удалённый TCP, всё ещё хранящий состояние, вернуть ACK с указанием ожидаемой позиции. Обычно проба не несёт данных и не сдвигает поток. Вариант с одним «мусорным» байтом оставили настраиваемым лишь для совместимости с ошибочными реализациями.
Ответ сообщает узкий факт: удалённый TCP сейчас обработал сегмент через пригодный двусторонний путь. Он не утверждает, что процесс приложения продвигается, учётные данные действуют, база доступна или следующая деловая операция завершится.
Необязательность была границей безопасности
RFC 1122 не обязал каждый TCP реализовывать keepalive. При наличии приложение должно было включать или выключать его отдельно для соединения, а исходное состояние — быть выключенным. Интервал простоя требовалось сделать настраиваемым, с умолчанием не меньше двух часов.
Так транспорт не выбирает семантику отказа за приложение. Терминальная сессия, соседство маршрутизаторов, пул базы и спящий датчик по-разному оценивают ложное закрытие, позднее обнаружение, сетевой трафик и удержание состояния. Отсутствие байтов не сообщает TCP, какая цена важнее.
Два часа никогда не означали, что партнёр умирает на 7200-й секунде. Это консервативная граница: без явного выбора приложения незапрошенные проверки должны быть редкими. Современная сводная спецификация RFC 9293 сохраняет это распределение полномочий. Десятилетия эксплуатации не превратили необязательную пробу в автоматическое определение жизни.
Один неотвеченный вопрос ничего не доказывает
Чистые ACK сами по себе не получают такой же гарантированной повторной передачи, как данные. Может потеряться проба, её ACK или оба могут задержаться из-за перегрузки. Поэтому RFC 1122 и RFC 9293 прямо запрещают признавать соединение мёртвым после единственного отсутствующего ответа.
Закрытие — действие, а не наблюдение. Стерев состояние и сообщив об отказе, локальный TCP может заставить приложение бросить транзакцию, освободить блокировку, выбрать замену или открыть второе соединение. Последствия вывода из краткой потери пакета могут пережить саму потерю.
Повторные пробы и порог повышают правдоподобие отказа. Но они выражают локальный выбор риска: после такого объёма отсутствующих свидетельств сохранять неопределённость дороже, чем закрыть соединение. Отсутствие не становится прямым свидетельством.
User timeout измеряет другое ожидание
TCP уже имел понятие пользовательской выдержки для отправленных, но неподтверждённых данных. RFC 5482 позднее определил опцию передачи предпочтения. Его вопрос: «Как долго переданные данные могут оставаться без ACK?», а не «Как давно молчит простаивающий партнёр?».
Разделение часов предотвращает конфликт политик. RFC 5482 отмечает, что некоторые настройки keepalive способны оборвать соединение, которое иначе пережило бы временную недоступность. При совместном использовании по этой спецификации таймер keepalive должен превышать принятый user timeout. Переданные данные, проба простоя и решение закрыть — связанные, но разные цепочки свидетельств.
У посредника появилась собственная память
В модели конец-конец состояние принадлежало узлам. NAT и stateful-middlebox добавили в путь ещё один истекающий реестр. Оба хоста могут правильно хранить соединение, тогда как посредник удалил отображение, необходимое следующему пакету.
RFC 5382 превратил двухчасовое умолчание в границу совместимости. Если NAT не способен определить активность концов установленного соединения, он не должен отбрасывать отображение раньше двух часов четырёх минут. Дополнительное время учитывает пакеты в пути.
Правило защищает ожидания концов, не делает NAT владельцем соединения и не доказывает соблюдение всеми устройствами. Обнаружив более короткие сроки, операторы учащают пробы. Отображение сохраняется, но взимается налог посредника: трафик нужен не приложению, а частному ящику, чтобы тот не забыл соединение.
Батарея предъявляет обратный счёт
На сервере от сети несколько пакетов кажутся дешёвыми. В экономичном устройстве каждая передача может разбудить радио и продлить дорогой активный период. RFC 9006 фиксирует противоречие: длинный стандартный интервал может не сохранить состояние middlebox, а короткий keepalive способен разрядить батарею.
Ни одна транспортная константа не распределит расходы правильно. Приложение знает, допустимо ли позднее переподключение; оператор измеряет срок состояния пути; устройство знает запас энергии. Иногда рациональнее вовсе не поддерживать соединение, а восстановить его при появлении работы.
Сердцебиение, которое не слышит приложение
Название «сердцебиение» преувеличивает область слуха keepalive. Ядро может ответить ACK, пока сервисный процесс завис. Прокси может поддерживать TCP, когда отказал backend. Здоровое приложение может быть намеренно приостановлено.
Проверка уровня приложения задаёт более сильный предметный вопрос: может ли сервис разобрать запрос, обратиться к состоянию и выдать допустимый ответ? Она дороже и всё равно не гарантирует будущую операцию. Два механизма стоит сочетать лишь после определения отказа, который должен видеть каждый.
Keepalive также не равен zero-window probe. Последний защищает повторное открытие окна после явного объявления нулевой ёмкости; keepalive исследует иначе тихое соединение. Похожие малые пакеты охраняют разные договоры.
За молчанием сохранилась презумпция невиновности
Долговечным решением стал не только трюк SND.NXT-1, но и отказ транспорта по умолчанию признавать молчание виновным.
Полученный ACK свидетельствует о недавнем ответе TCP, не о здоровье приложения. Отсутствующий ACK означает неопределённость, а не смерть. Настроенная серия пропусков может оправдать локальное закрытие лишь потому, что приложение выбрало бюджет риска, а не потому, что Интернет дал уверенность.
Keepalive остался необязательным: сторона, несущая последствия, должна сохранить решение. TCP предложил способ спросить, но не заявил права объяснять, почему ответа нет.
Источники и границы свидетельств
RFC 793 задаёт исходное соединение и user timeout; RFC 1122 — договор keepalive 1989 года; RFC 5382 — сроки NAT; RFC 5482 — отделение user timeout; RFC 9006 — энергетический компромисс; RFC 9293 — сводные текущие правила. Они не устанавливают умолчание каждой платформы, срок каждой middlebox или значение здоровья каждого приложения.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров
