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

Анатомия игровых лагов › Первопричины повторных передач TCP

Истечение записи NAT или балансировщика посреди соединения NAT / load balancer mapping expired mid-connection

ID причины rt-mapping · Основной ответственный Команда разработки · Разработка клиента · Совместно Команда разработки · Разработка сервера, Команда инфраструктуры · Сетевая инфраструктура, Команда инфраструктуры · Серверная инфраструктура

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

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

Почему Соединение, по которому какое-то время не ходят пакеты (игрок отошёл, сидит в лобби) → Следствие NAT роутера, CGNAT провайдера, файрвол, балансировщик нагрузки или облачная группа безопасности удаляют неактивную запись → На экране Как только игрок снова начинает двигаться, идут повторные передачи и затем дисконнект, или дисконнект сразу

Симптомы
Дисконнект, Фриз
Факторы
Потери
У кого
Только у меня, Один регион или провайдер
Когда
После бездействия
Ответственные
Основной ответственный Команда разработки · Разработка клиента · Совместно Команда разработки · Разработка сервера, Команда инфраструктуры · Сетевая инфраструктура, Команда инфраструктуры · Серверная инфраструктура
Команда разработки: задачи
Клиент: слать хартбиты с интервалом не больше половины самого короткого таймаута простоя (запись в роутере игрока и в CGNAT провайдера надёжно обновляют только пакеты, исходящие изнутри, а таймауты мы изменить не можем, поэтому слать должен клиент), при обрыве автоматически переподключаться. Сервер: отвечать на хартбиты и, если их нет определённое время, первым закрывать соединение (сократить интервал TCP keepalive опциями сокета вроде TCP_KEEPIDLE, быстрее замечать обрыв через TCP_USER_TIMEOUT), продолжать сессию по токену сессии.
Команда инфраструктуры: задачи
Сеть: собрать таймауты простоя файрволов и балансировщиков на маршруте и передать команде разработки, на наших файрволах и балансировщиках при необходимости увеличить. Серверы и ОС: проверить время отслеживания соединений в облачной группе безопасности и передать команде разработки.
Цифры для ориентира
Сколько держится запись TCP, зависит от устройства: от нескольких минут до нескольких часов. Если облачная группа безопасности отслеживает соединения, у типов инстансов AWS Nitro v6 запись удаляется по умолчанию через 350 с (у остальных типов через 5 дней, см. причину «Истечение отслеживания соединений в облачной группе безопасности»). TCP keepalive в Linux по умолчанию срабатывает так: «проверить после 2 часов простоя», а это позже, чем у большинства устройств.
На графике
Массовый обрыв соединений · число обрывов, время бездействия перед обрывом
Где смотреть
Посмотреть последние минуты оборвавшихся соединений в захвате пакетов на стороне сервера, у живых соединений смотреть время простоя по lastsnd и lastrcv в ss -ti (сколько ms прошло с последней отправки и последнего приёма). Заодно смотреть TcpExtTCPAbortOnTimeout в nstat (сколько соединений брошено по истечении таймера)
Подтверждает
У каждого оборвавшегося соединения время простоя перед обрывом превысило примерно одно и то же значение (таймаут простоя устройства на маршруте, например 350 с в группе безопасности инстансов AWS Nitro v6), и с первого пакета после простоя идут одни повторные передачи без ACK, пока отправитель не прекратит попытки, или сразу возвращается RST
Опровергает
Если обрывы бывают и во время игры независимо от времени простоя, причина другая («Смена маршрута и неисправный путь ECMP», «Отбрасывание пакетов файрволом или conntrack»). Если хартбиты по соединению ходят с интервалом не больше половины самого короткого таймаута простоя, эта причина исключается
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)

Источники

  1. RFC 5382: NAT Behavioral Requirements for TCP IETF
    Рекомендация: таймаут простоя TCP-соединения в NAT должен быть не меньше 2 часов 4 минут (с учётом того, что устройство может удалить неактивную сессию раньше)
  2. RFC 4787: Network Address Translation (NAT) Behavioral Requirements for Unicast UDP IETF
    Запись NAT должна обновляться пакетами, исходящими изнутри (REQ-6), обновление пакетами, входящими снаружи, необязательно (для UDP)
  3. Amazon EC2 security group connection tracking AWS
    Таймаут отслеживания неактивных TCP-соединений по умолчанию: 350 с у типов инстансов Nitro v6, 432 000 с (5 дней) у остальных. Рекомендация слать keepalive с интервалом меньше 5 минут
  4. IP Sysctl Linux kernel
    tcp_keepalive_time по умолчанию 2 часа
  5. tcp(7) — Linux manual page Linux man-pages
    TCP_KEEPIDLE (время простоя до начала keepalive), TCP_USER_TIMEOUT (сколько ждать подтверждения данных, прежде чем закрыть соединение)
  6. RFC 5482: TCP User Timeout Option IETF
    Пользовательский таймаут TCP: через сколько времени без подтверждения отправленных данных закрывать соединение
  7. ss(8) — Linux manual page iproute2
    lastsnd и lastrcv в ss -i: время с последней отправки и последнего приёма (ms)
  8. SNMP counter Linux kernel
    TcpExtTCPAbortOnTimeout: сколько TCP-соединений брошено без RST по истечении таймера

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

Тот же слой: Первопричины повторных передач TCP

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

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