게임 렉 백서 › L8 소켓과 프로토콜
TCP HOL 블로킹 Head-of-line blocking
원인 ID sk-hol · 주 담당 게임개발팀·서버 개발 · 함께 게임개발팀·클라이언트 개발
그림과 실험이 있는 원본 카드로 열기 →
TCP는 순서를 지키려고 잃어버린 패킷 하나를 다시 받을 때까지 뒤에 도착한 패킷을 게임에 넘기지 않습니다.
왜 패킷 하나가 사라짐 → 그러면 뒤 패킷들은 도착했지만 수신 버퍼에서 대기 → 화면에서는 멈췄다가 한꺼번에 풀리며 몰아치기
- 증상
- 멈춤, 몰아치기
- 요인
- 손실, 정체
- 누가 겪나
- 나만
- 언제
- 가끔 무작위로
- 담당
- 주 담당 게임개발팀·서버 개발 · 함께 게임개발팀·클라이언트 개발
- 게임개발팀 할 일
- 서버: 실시간 위치는 UDP, 꼭 필요한 것만 신뢰성 전송, 스트림 여러 개로 나누기. 클라이언트: 서버와 같은 방식(UDP, 채널 분리)으로 네트워크 처리 변경.
- 수치 감각
- 패킷 하나를 잃으면 최소 왕복 시간 + α, 재전송까지 잃으면 수백 ms~수 초 멈춥니다.
- 그래프에서는
- 끊겼다가 몰아서 · 연결별 수신량, 재전송 수
- 확인할 곳
- 서버 쪽 패킷 캡처(tcpdump·Wireshark)로 그 유저 연결에서 재전송 패킷과 그 앞뒤의 공백을 보고, 서버 전체는 nstat -az의 TcpRetransSegs 증가량을 봄
- 이러면 맞음
- 멈춘 구간이 패킷 하나의 재전송으로 시작하고 재전송 패킷이 도착한 직후 밀린 데이터가 한꺼번에 처리됨(수신량이 0이다가 몰림)
- 이러면 아님
- UDP로 통신하는 게임이면 해당 없음. 재전송이 없는데 멈추면 서버 틱 쪽(“틱 예산 초과”)을 봄
- 확인 수단
- 인프라 도구로 확인(게임 코드 불필요)
출처
- RFC 9293: Transmission Control Protocol (TCP) IETF
TCP는 신뢰성 있는, 순서를 지키는 바이트 스트림 서비스 - RFC 5681: TCP Congestion Control IETF
중복 ACK 3개로 손실을 감지해 빠른 재전송, 그렇지 않으면 재전송 타이머를 기다림 - RFC 6298: Computing TCP's Retransmission Timer IETF
재전송 타이머가 만료될 때마다 두 배로 늘리는 백오프 - net/ipv4/proc.c (Linux v6.12) Linux kernel
nstat이 보여 주는 카운터 이름: Tcp 그룹의 RetransSegs(재전송한 세그먼트 수)
함께 보면 좋은 원인
같은 층: L8 소켓과 프로토콜
같은 증상(멈춤)의 다른 층 원인
그림과 실험이 있는 원본 카드 보기