Истечение записи 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»). Если хартбиты по соединению ходят с интервалом не больше половины самого короткого таймаута простоя, эта причина исключается
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Источники
RFC 5382: NAT Behavioral Requirements for TCPIETF Рекомендация: таймаут простоя TCP-соединения в NAT должен быть не меньше 2 часов 4 минут (с учётом того, что устройство может удалить неактивную сессию раньше)
Amazon EC2 security group connection trackingAWS Таймаут отслеживания неактивных TCP-соединений по умолчанию: 350 с у типов инстансов Nitro v6, 432 000 с (5 дней) у остальных. Рекомендация слать keepalive с интервалом меньше 5 минут
IP SysctlLinux kernel tcp_keepalive_time по умолчанию 2 часа
tcp(7) — Linux manual pageLinux man-pages TCP_KEEPIDLE (время простоя до начала keepalive), TCP_USER_TIMEOUT (сколько ждать подтверждения данных, прежде чем закрыть соединение)
RFC 5482: TCP User Timeout OptionIETF Пользовательский таймаут TCP: через сколько времени без подтверждения отправленных данных закрывать соединение
ss(8) — Linux manual pageiproute2 lastsnd и lastrcv в ss -i: время с последней отправки и последнего приёма (ms)
SNMP counterLinux kernel TcpExtTCPAbortOnTimeout: сколько TCP-соединений брошено без RST по истечении таймера