Keepalive по умолчанию: 2 часа TCP keepalive defaults
ID причины sk-keepalive · Основной ответственный Команда разработки · Разработка сервера · Совместно Команда разработки · Разработка клиента, Команда инфраструктуры · Серверная инфраструктура
Если другая сторона пропадает без сигнала о закрытии, TCP замечает это очень нескоро. Keepalive (механизм TCP, который проверяет, живо ли неактивное соединение) по умолчанию выключен, а если его включить, проверка начинается только после 2 часов простоя.
Почему Клиент пропадает без сигнала о закрытии: выключилось питание или оборвалась связь → Следствие Сервер считает соединение живым (keepalive по умолчанию 7 200 с, а если оставались неотправленные данные, до отказа от повторных передач около 15 минут) → На экране В мире остаётся персонаж-фантом, а при перезаходе ошибка «Аккаунт уже в игре»
Основной ответственный Команда разработки · Разработка сервера · Совместно Команда разработки · Разработка клиента, Команда инфраструктуры · Серверная инфраструктура
Команда разработки: задачи
Сервер: отвечать на хартбиты, а если их долго нет, первым закрывать соединение (настроить TCP_KEEPIDLE и TCP_USER_TIMEOUT). При переподключении заменять старую сессию по токену сессии и продолжать игру. Клиент: отправлять хартбиты на уровне игры с интервалом от нескольких до десятков секунд (не больше половины самого короткого таймаута простоя), при обрыве автоматически переподключаться.
Команда инфраструктуры: задачи
Для сокетов, которым код не задаёт свои значения, снизить значения ядра по умолчанию (tcp_keepalive_time и др.; они действуют только на сокеты с включённым SO_KEEPALIVE).
Цифры для ориентира
По умолчанию Linux начинает проверку после 7 200 с простоя, отправляет 9 проб с интервалом 75 с и, если ответа так и нет, разрывает соединение. Всего выходит около 2 ч 11 мин. Windows по умолчанию тоже начинает проверку только после 2 часов простоя.
На графике
Высоко только у некоторых · время с последнего приёма по соединениям
Где смотреть
Посмотреть через ss -tnoi lastrcv (сколько ms прошло с последнего приёма) и таймер keepalive (timer:(keepalive,…)) по соединениям и сопоставить с записями игрового сервера об отказах «Аккаунт уже в игре»
Подтверждает
Остаются соединения ESTABLISHED с lastrcv от нескольких минут до нескольких часов, а перезаход с этого аккаунта отклоняется с ошибкой «Аккаунт уже в игре»
Опровергает
Если давно молчащих соединений нет, а «Аккаунт уже в игре» всё равно появляется, дело в коде очистки сессий на игровом сервере
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Источники
tcp(7) — Linux manual pageLinux man-pages После 7 200 с простоя 9 проб с интервалом 75 с (ещё около 11 минут). Действует только на сокеты с включённым SO_KEEPALIVE. Опции TCP_KEEPIDLE и TCP_USER_TIMEOUT