Все углублённые блоки
Углублённые блоки
Блок 01 / Углублённый разбор

DNS, достижимость и ограничения транспорта

Различаем имя, маршрут и живой сервис; исследуем TTL, байтовый поток, окна TCP и стоимость сетевого пути.

Команда перенесла API Клуба на новый IP, но часть клиентов продолжает обращаться к старому серверу. Другие уже используют новый адрес и получают timeout. Инженер предлагает «очистить DNS и добавить серверов». Здесь как минимум три независимых вопроса: какой адрес получил клиент, может ли установить соединение и может ли сервис завершить запрос.

После этого блока вы сможете разделить эти вопросы по наблюдениям, посчитать срок DNS-кэша и объём данных в пути, отличить медленного получателя от перегруженного маршрута. До начала нужны роли клиента и сервера, единицы времени и содержание базовой главы об HTTP.

Достижимость — цепочка условий

Приложение передаёт имя resolver, получает адрес и открывает сокет. IP помогает маршрутизаторам пересылать пакеты; порт выбирает транспортный endpoint на узле. TCP-соединение определяется адресами и портами обеих сторон. Путь HTTP-запроса появляется позже, внутри прикладного сообщения. Номер события 42 не участвует в маршрутизации IP.

Сокет — интерфейс процесса к сетевому обмену, а не удалённый пользователь. Один человек может открыть несколько соединений, одно соединение HTTP/2 — нести запросы нескольких вкладок. Ограничение числа соединений и ограничение действий пользователя защищают разные ресурсы.

Маршрут может проходить через NAT, firewall, балансировщик и несколько сетей. NAT меняет адреса/порты по своим правилам; firewall может разрешать TCP 443 и блокировать UDP 443. Успешный ping не доказывает доступность HTTPS: ICMP, TCP и приложение проверяют разные условия. Неуспешный ping тоже не доказывает недоступность HTTPS, если ICMP фильтруется.

Для диагностики нужны категории: DNS error, connect refused, connect timeout, TLS error, HTTP error, business error. 503 уже является HTTP-ответом от какого-то участника пути; его мог сформировать proxy. Таймаут без ответа не доказывает, что запрос не дошёл. Транспортную семантику TCP задаёт RFC 9293, роли HTTP-посредников — RFC 9110, §3.7.

Локальный опыт: connect и HTTP — разные события

В первом терминале создайте пустую временную папку и запустите учебный сервер, доступный только с этого компьютера:

network_lab_dir=$(mktemp -d)
python3 -m http.server 8765 --bind 127.0.0.1 --directory "$network_lab_dir"

Во втором выполните:

curl -v --connect-timeout 1 --max-time 3 http://127.0.0.1:8765/
curl -v --connect-timeout 1 --max-time 3 http://127.0.0.1:8765/missing

Первый запрос обычно получает 200, второй — 404, если файл действительно отсутствует. В обоих случаях TCP-соединение установлено и сервер ответил. Затем остановите сервер Ctrl+C и повторите первый запрос: на обычном loopback без firewall ожидается отказ соединения. Это локальный connect refusal, а не HTTP 404. Если порт занят, выберите другой и измените обе команды; если Python отсутствует, разберите ту же трассу на бумаге. Не выводите из этого опыта поведение timeout на удалённом маршруте: там пакеты могут молча отбрасываться.

Resolver, authoritative и кэш

Stub resolver на устройстве обычно спрашивает настроенный рекурсивный resolver. Тот отвечает из кэша либо ищет данные через делегирование: серверы сообщают, кто отвечает за нужную часть пространства имён. Authoritative server владеет данными зоны; recursive resolver собирает ответ для клиента. Один процесс способен выполнять обе роли, но обязанности надо различать.

Записи имеют тип: A — IPv4, AAAA — IPv6, CNAME — другое имя, NS — серверы зоны. После получения CNAME может понадобиться разрешить целевое имя. Это не HTTP redirect: браузер не получает автоматически новый URL и путь. У записей цепочки могут быть разные сроки.

TTL ограничивает время использования кэшированных данных. Если resolver получил ответ в 12:00 с TTL 300 секунд, его обычный срок истечения — 12:05. Ответ через минуту имеет меньший оставшийся срок. Изменение authoritative-записи не меняет уже сохранённую копию. Основной механизм описан в RFC 1035, §3.2.1 и §7.4.

Отрицательные ответы тоже могут кэшироваться. NXDOMAIN означает отсутствие имени, NODATA — отсутствие запрошенных данных для существующего имени. Отрицательный срок вычисляется по данным SOA согласно RFC 2308. Ошибка опечатки, которую исправили на сервере, поэтому может некоторое время оставаться видимой отдельным клиентам.

Нельзя обещать, что все клиенты переключатся строго за TTL. Есть кэш приложения и его конфигурация, особенности resolver, поведение при отказах и уже установленные соединения. DNS не является проверкой здоровья сервиса. Низкий TTL повышает частоту поиска и зависимость от доступности DNS; он не бесплатный переключатель.

Практика: миграция без мгновенного переключения

В t=−1 resolver получил старый IP с TTL 300 секунд. В t=0 команда снизила TTL authoritative-записи до 30. В t=60 изменила IP. Когда этот resolver перестанет использовать старый ответ в обычной модели? Можно ли выключить старый сервер в t=90?

Подсказка. Новый TTL относится к новым полученным данным.

Разбор. Срок старой копии заканчивается в t=299. Поэтому t=90 слишком рано уже в модели исправных кэшей. После истечения клиент может получить новый адрес, но его открытое TCP-соединение не обязано закрыться. План должен заранее понизить TTL, выдержать предыдущие сроки, направить новые соединения на новый адрес и отдельно завершить старые. Если цель — аварийное переключение, потребуется механизм маршрутизации и клиентского восстановления помимо DNS.

Локальное наблюдение

Если установлен dig, выполните два чтения одной записи:

dig example.com A +noall +answer
dig example.com A +noall +answer
dig example.com AAAA +noall +answer

В answer видны имя, TTL, класс, тип и данные. Повторный TTL часто меньше, но это не обязательный результат: resolver может выбрать другой кэш, обновить запись или вообще не кэшировать её. Не используйте пример как публичный тест failover: вы не управляете его зоной. dig +trace example.com показывает делегирование через прямые запросы, если сеть их разрешает; это не трасса DNS конкретного браузера с DoH и локальным кэшем.

Сдайте вывод, выбранный resolver и объяснение различия A/AAAA. Если команды нет, разберите предоставленную временную линию; установка дополнительного инструмента не обязательна для понимания TTL.

TCP: байты, подтверждение и два окна

Приложение пишет байты в TCP, а реализация транспорта делит их на сегменты и собирает у получателя. Пакет может потеряться, сегмент — прийти повторно или вне порядка. TCP скрывает это за упорядоченным байтовым потоком. Он не сохраняет границы вызовов write: два вызова могут быть прочитаны вместе или один — несколькими чтениями. Прикладной протокол должен сам описывать framing, то есть границы сообщений.

ACK говорит о приёме данных транспортом. Получатель мог ещё не прочитать их, не проверить права и не обратиться к базе. Поэтому «получен ACK» и «заказ сохранён» нельзя объединить в один статус. Закрытие соединения после отправки тоже не определяет бизнес-исход записи.

При установке TCP стороны обмениваются SYN, SYN-ACK и ACK, согласуя начальные sequence numbers. Это не handshake HTTP и не проверка сертификата. Потерянные данные могут передаваться повторно; клиентское время ожидания и решение транспорта о продолжении соединения имеют разные сроки. TCP keepalive и отдельный heartbeat приложения не дают абсолютного доказательства отказа: сеть может задержать сообщения. Для конкретного действия нужен deadline и правило неизвестного исхода.

Окно приёма rwnd показывает, сколько незавершённых данных получатель готов принять. Если приложение читает медленно и буфер заполнен, окно уменьшается: это flow control. Окно перегрузки cwnd ограничивает данные в пути по состоянию сети: это congestion control. Отправка ограничена меньшим из этих окон. Механизм и базовые алгоритмы описывает RFC 5681, §2–3.

Представьте два опыта. В первом клиент не читает ответ, хотя маршрут свободен: уменьшится окно приёма, сервер может копить данные. Во втором клиент читает быстро, но маршрут теряет пакеты: понадобятся повторные передачи и реакция управления перегрузкой. В обоих случаях throughput падает, но увеличение reader speed помогает только первому. Потеря также может быть следствием ошибок связи, поэтому отдельный lost packet не доказывает очередь на маршрутизаторе.

Flow control TCP не заменяет ограничение дорогой работы приложения. Сервер может быстро прочитать десять тысяч запросов из сокетов и поставить их в огромную очередь БД. Транспорт видит свободный буфер, а приложение уже перегружено. Ограничивать admission и очереди нужно у ресурса, который расходуется на обработку.

RTT, bandwidth и данные в пути

RTT включает путь туда и обратно и ожидания на маршруте. Bandwidth задаёт скорость передачи; serialization — время помещения байтов в канал. Для полезного ответа 1 МБ при 10 Мбит/с только передача требует около 0,8 секунды в десятичных единицах. К ней добавляются установление связи, ожидание сервиса и другие задержки. Высокая пропускная способность не устраняет большой RTT.

Для длительной передачи полезно оценить bandwidth-delay product: BDP = bandwidth × RTT. При 100 Мбит/с и RTT 80 мс это 8 Мбит, около 1 МБ. При тех же 100 Мбит/с и RTT 8 мс — 100 КБ. Если разрешённый объём незавершённых данных намного меньше BDP, отправитель не сможет постоянно заполнять канал. Например, 64 КБ за RTT 80 мс соответствует примерно 6,4 Мбит/с; это идеализированная оценка с постоянным окном, без потерь и других ограничений.

Большие буферы не гарантируют улучшение. Они расходуют память и способны удерживать больше байтов в очереди, повышая latency. Конкурирующие соединения делят маршрут, а congestion control меняет окно во времени. BDP — проверка порядка величин, а не готовая настройка TCP или прогноз всей системы.

Самостоятельная диагностика

У Клуба два симптома. Пользователь A получает старый IP через DNS и успешный ответ. Пользователь B получает новый IP, TCP устанавливается, но запрос чтения висит. Предложите по две гипотезы и наблюдения, которые их различают. Затем рассчитайте BDP нового маршрута: 40 Мбит/с и 50 мс.

Разбор и критерии. Для A проверить TTL/кэш и существующее соединение отдельно. Для B проверить очередь приложения/БД и сетевую доставку: trace этапов, время ожидания пула, чтение сокета, retransmissions и окно приёма. Успешный connect не доказывает отсутствие последующего сетевого сбоя. BDP равен 2 Мбит, или 250 КБ. Ответ «DNS сломан, добавим CPU» не засчитывается: он не связывает изменения с наблюдаемым механизмом.

Для защиты решения покажите три границы: поиск адреса, доставка байтов, завершение операции. Назовите факт, которым проверяется каждая. Продолжение — TLS, HTTP и посредники.

Проверьте себя

Resolver получил старый IP в t=−1 с TTL 300 секунд. В t=0 authoritative TTL снизили до 30, в t=60 сменили IP. Когда в обычной модели истекает старая кэшированная запись и что известно об открытом соединении?

Запишите ход рассуждений, расчёты и вопросы. Сохраните текст перед уходом со страницы. После входа в аккаунт ответ участвует в общей синхронизации прогресса. Автоматической оценки архитектуры здесь нет.