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

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

Блокирующая отправка из-за медленного клиента Blocking send on a full socket

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

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

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

Почему Буфер отправки медленного клиента заполнен → Следствие Отправка блокирующая, и поток сервера ждёт, пока в буфере освободится место → На экране У всех, кого обслуживает этот поток, фриз или слоумо

Симптомы
Фриз, Слоумо
Факторы
Остановка
У кого
Одна локация или канал, Весь сервер
Когда
Изредка, случайно, При наплыве игроков
Ответственные
Основной ответственный Команда разработки · Разработка сервера
Команда разработки: задачи
Перейти на неблокирующую отправку, ограничить очередь отправки для каждого клиента, выбрасывать устаревшие обновления.
На графике
Случайные всплески · время тика сервера, Send-Q по соединениям
Где смотреть
Найти через ss -tn соединения, у которых Send-Q (байты без ACK или ещё не отправленные) заполнен на весь буфер отправки, и в момент всплеска времени тика посмотреть в дампе потоков (стеках) игрового сервера, нет ли потоков, застрявших в вызове send
Подтверждает
Когда есть медленное соединение с заполненным Send-Q, обслуживающий его поток стоит в send, и вместе с ним замирают только игроки, которых обслуживает тот же поток
Опровергает
Если остановившийся поток ждёт вне send (на блокировке, в вызове БД), это «Конкуренция за блокировки» или «Синхронные вызовы в игровом потоке»
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)

Источники

  1. send(2) — Linux manual page Linux man-pages
    Если в буфере отправки нет места, send() блокируется, а в неблокирующем режиме сразу возвращает EAGAIN
  2. send function (winsock2.h) Microsoft
    В Winsock send тоже блокируется при нехватке места в буфере, если сокет не в неблокирующем режиме
  3. net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel
    Значения Recv-Q и Send-Q в ss: у слушающего сокета это число подключений, ждущих accept, и лимит backlog, у подключённого сокета это байты, ещё не прочитанные приложением, и отправленные байты без ACK

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

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

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

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