한국어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 같은 프레임 멈춤 원인 해결. 서버: 소켓을 읽는 스레드가 막히는 원인 해결.
인프라팀 할 일
서버의 nstat TcpExtTCPToZeroWindowAdv(서버가 수신 윈도우를 0으로 알린 횟수)를 모니터링에 추가(늘면 서버 쪽이므로 서버 개발에 전달), 서버 쪽 패킷 캡처 제공.
그래프에서는
끊겼다가 몰아서 · 연결별 수신량, 제로 윈도우 횟수
확인할 곳
패킷 캡처에서 Wireshark 필터 tcp.analysis.zero_window로 윈도우 0을 알린 쪽을 찾음. 서버의 nstat에서는 TcpExtTCPToZeroWindowAdv(서버가 윈도우 0을 알림)와 TcpExtTCPWinProbe(상대의 윈도우 0에 프로브를 보냄)를 나눠 보고, 서버 소켓의 Recv-Q(ss에서 프로그램이 아직 읽지 않은 바이트)를 봄
이러면 맞음
멈춘 동안 재전송은 없고 제로 윈도우와 프로브만 오감. 서버의 TcpExtTCPToZeroWindowAdv나 서버 소켓의 Recv-Q가 늘면 서버가 제때 읽지 못하는 것, TcpExtTCPWinProbe가 늘면 클라이언트가 제때 읽지 못하는 것
이러면 아님
캡처에 제로 윈도우가 없고 같은 데이터가 다시 보내지면 손실이나 불필요한 재전송 쪽 원인
확인 수단
인프라 도구로 확인(게임 코드 불필요)
실제 사례
Roblox 2021: Roblox 73시간 장애: 서비스 디스커버리(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이 아닌 값에서 0으로 알린 횟수
  5. net/ipv4/proc.c Linux kernel
    nstat에 나오는 카운터 이름 TCPToZeroWindowAdv·TCPWinProbe
  6. net/ipv4/tcp_output.c Linux kernel
    TCPWinProbe: 상대 수신 윈도우가 0일 때 보내는 프로브(tcp_send_probe0)마다 증가
  7. net/ipv4/tcp_diag.c Linux kernel
    ss의 Recv-Q는 연결이면 받았지만 프로그램이 아직 읽지 않은 바이트 수

함께 보면 좋은 원인

같은 층: TCP 재전송의 근본 원인

같은 증상(멈춤)의 다른 층 원인

그림과 실험이 있는 원본 카드 보기