Когда несколько процессов принимают трафик на одном порту, ядро закрепляет каждое подключение за процессом по хешу адреса и больше его не меняет. Если один процесс зависает, ждут только игроки, закреплённые за ним.
Почему Шлюз или сервер авторизации запускает несколько процессов с SO_REUSEPORT → Следствие Если один процесс останавливается из-за GC или перегрузки, закреплённые за ним новые подключения и UDP-пакеты к другим процессам не переходят → На экране Только у части игроков ошибка входа или фриз. При перезапуске со сменой числа процессов часть UDP-сессий обрывается
Основной ответственный Команда разработки · Разработка сервера · Совместно Команда инфраструктуры · Серверная инфраструктура
Команда разработки: задачи
Не допускать остановок принимающего потока, реализовать передачу сессий при перезапуске.
Команда инфраструктуры: задачи
Следить за очередью подключений каждого процесса (Recv-Q в ss), а если при деплое меняется число процессов, следовать процедуре передачи сессий.
На графике
Высоко только у некоторых · очередь подключений (Recv-Q) по слушающим сокетам
Где смотреть
Посмотреть через ss -ltnp для каждого слушающего сокета на этом порту Recv-Q (число подключений, ждущих accept) и процесс-владелец, сравнить пропускную способность процессов
Подтверждает
Из нескольких сокетов на одном порту Recv-Q постоянно растёт только у одного, а процесс этого сокета стоит или его пропускная способность близка к 0
Опровергает
Если Recv-Q растёт равномерно у всех сокетов, это общая перегрузка («Переполнение очереди подключений (backlog)»)
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Источники
socket(7) — Linux manual pageLinux man-pages С SO_REUSEPORT несколько сокетов делают bind на один адрес и делят между собой TCP-подключения и UDP-пакеты
Why does one NGINX worker take all the load?Cloudflare SO_REUSEPORT делит подключения по очередям воркеров простым хешем, поэтому если один воркер застрял, встают все подключения в его очереди
net/ipv4/tcp_diag.c (Linux v6.12)Linux kernel Значения Recv-Q и Send-Q в ss: у слушающего сокета это число подключений, ждущих accept, и лимит backlog, у подключённого сокета это байты, ещё не прочитанные приложением, и отправленные байты без ACK