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

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

Нулевое окно (остановка, похожая на повторную передачу) Zero window, often mistaken for retransmission

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

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

Если программа-получатель не успевает вовремя читать сокет и буфер заполняется, отправитель останавливает передачу и шлёт только пробы нулевого окна. С линией связи это не связано.

Почему Кадр на клиенте завис или поток сервера заблокирован, и сокет не читается → Следствие Окно приёма становится 0, отправитель останавливает передачу и шлёт только пробы (интервал постепенно растёт) → На экране Фриз, потом перемотка. В захвате пакетов видно «ZeroWindow», потерь нет

Симптомы
Фриз, Перемотка
Факторы
Остановка
У кого
Только у меня, Весь сервер
Когда
При наплыве игроков, Изредка, случайно
Ответственные
Основной ответственный Команда разработки · Разработка клиента · Совместно Команда разработки · Разработка сервера, Команда инфраструктуры · Серверная инфраструктура
Команда разработки: задачи
В захвате пакетов сначала найти сторону, отправившую ZeroWindow (ту, что не успевает читать сокет), читать сетевые данные непрерывно в отдельном потоке, задать подходящий размер буфера приёма. Клиент: устранить причины зависания кадров вроде загрузки и GC. Сервер: устранить причины блокировки потока, читающего сокет.
Команда инфраструктуры: задачи
Добавить в мониторинг TcpExtTCPToZeroWindowAdv из nstat на сервере (сколько раз сервер объявил окно приёма равным 0; если растёт, проблема на стороне сервера, передать разработке сервера), предоставлять захваты пакетов на стороне сервера.
На графике
Провал, затем пачка · объём приёма по соединениям, число нулевых окон
Где смотреть
В захвате пакетов найти фильтром Wireshark tcp.analysis.zero_window сторону, объявившую окно 0. В nstat на сервере смотреть отдельно TcpExtTCPToZeroWindowAdv (сервер объявил окно 0) и TcpExtTCPWinProbe (проба отправлена в ответ на окно 0 у другой стороны), а также Recv-Q сокета на сервере (байты в ss, ещё не прочитанные программой)
Подтверждает
Во время фриза повторных передач нет, ходят только нулевые окна и пробы. Если растут TcpExtTCPToZeroWindowAdv или Recv-Q сокета на сервере, не успевает читать сервер, если растёт TcpExtTCPWinProbe, не успевает читать клиент
Опровергает
Если нулевых окон в захвате нет, а одни и те же данные отправляются повторно, причина в потерях или ложных повторных передачах
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Реальные инциденты
Roblox 2021: Сбой Roblox на 73 часа: конкуренция в кластере service discovery (Consul)

Источники

  1. RFC 9293: Transmission Control Protocol (TCP) IETF
    Если окно приёма равно 0, отправитель шлёт пробы нулевого окна и экспоненциально увеличивает интервал между ними
  2. 7.5. TCP Analysis Wireshark
    TCP ZeroWindow: пакет, которым получатель объявляет окно 0 и заставляет отправителя остановить передачу
  3. Display Filter Reference: Transmission Control Protocol Wireshark
    Фильтры отображения tcp.analysis.zero_window и tcp.analysis.zero_window_probe
  4. SNMP counter Linux kernel
    TcpExtTCPToZeroWindowAdv: сколько раз окно приёма объявлено равным 0 после ненулевого значения
  5. net/ipv4/proc.c Linux kernel
    Названия счётчиков в выводе nstat: TCPToZeroWindowAdv, TCPWinProbe
  6. net/ipv4/tcp_output.c Linux kernel
    TCPWinProbe растёт с каждой пробой (tcp_send_probe0), отправленной при нулевом окне приёма у другой стороны
  7. net/ipv4/tcp_diag.c Linux kernel
    Recv-Q в ss для соединения: число байт, которые получены, но ещё не прочитаны программой

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

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

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

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