한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Анатомия игровых лагов › L8 Сокеты и протоколы

TCP RTO и экспоненциальный backoff RTO and exponential backoff

ID причины sk-rto · Основной ответственный Команда разработки · Разработка сервера · Совместно Команда разработки · Разработка клиента

Открыть карточку в основной версии с иллюстрациями и экспериментами →

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

Почему Связь ненадолго обрывается, и повторные передачи тоже одна за другой не доходят → Следствие Ожидание до следующей попытки каждый раз удваивается: 0,3 → 0,6 → 1,2 → 2,4 с (при пинге 100 ms) → На экране Связь пропала на 1 с, а фриз в игре длится больше 2 с. Если обрыв дольше, в итоге дисконнект

Симптомы
Фриз, Дисконнект
Факторы
Потери, Остановка
У кого
Только у меня
Когда
Изредка, случайно, В движении и при смене локации
Ответственные
Основной ответственный Команда разработки · Разработка сервера · Совместно Команда разработки · Разработка клиента
Команда разработки: задачи
Сервер: отвечать на хартбиты, а если их долго нет, первым закрывать соединение (сократить время до отказа через TCP_USER_TIMEOUT), восстанавливать сессию по токену, рассмотреть надёжный UDP. Клиент: часто отправлять хартбиты, а если ответы пропали, сразу переподключаться, не дожидаясь повторных передач TCP.
Цифры для ориентира
Минимальный RTO (время ожидания перед повторной передачей) в Linux равен «пинг + 200 ms», а при установке соединения он начинается с 1 секунды. С настройкой по умолчанию (tcp_retries2=15) повторные передачи могут раз за разом не проходить, но TCP отказывается от соединения только примерно через 15 минут.
На графике
Провал, затем пачка · RTO и backoff по соединениям, число срабатываний RTO
Где смотреть
Посмотреть через ss -ti у зависшего соединения rto (ожидание перед повторной передачей в ms) и backoff (число срабатываний подряд), а по серверу в целом прирост TcpExtTCPTimeouts (число срабатываний таймера повторной передачи) в nstat -az
Подтверждает
У зависшего соединения backoff 1 и больше, rto вырос до секунд, и в этот момент растёт TCPTimeouts
Опровергает
Если всё решается быстрой повторной передачей и RTO не срабатывает, остановка короткая. Тогда это «HOL-блокировка в TCP»
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)

Источники

  1. RFC 6298: Computing TCP's Retransmission Timer IETF
    Начальный RTO 1 секунда, при каждом срабатывании таймера RTO удваивается (экспоненциальная задержка повтора)
  2. net/ipv4/tcp_input.c (Linux v6.12) Linux kernel
    В Linux RTO = сглаженный RTT + разброс RTT, а нижняя граница разброса равна tcp_rto_min (200 ms), поэтому RTO не меньше RTT+200 ms
  3. IP Sysctl Linux kernel
    tcp_rto_min_us по умолчанию 200 ms, начальный RTO для запроса на подключение 1 секунда, при tcp_retries2=15 до отказа проходит минимум 924,6 с (около 15 минут)
  4. ss(8) — Linux manual page iproute2
    rto (таймер повторной передачи, ms) и backoff (число экспоненциальных удвоений) в выводе -i
  5. net/ipv4/proc.c (Linux v6.12) Linux kernel
    Имена счётчиков, которые показывает nstat: TCPTimeouts в группе TcpExt
  6. net/ipv4/tcp_timer.c (Linux v6.12) Linux kernel
    При каждом срабатывании таймера повторной передачи увеличивается TCPTimeouts, backoff растёт на единицу, а RTO удваивается (до максимального значения)

Смотрите также

Тот же слой: L8 Сокеты и протоколы

Причины с тем же симптомом (Фриз) на других слоях

Карточка в основной версии с иллюстрациями и экспериментами