게임 렉 백서 › TCP 재전송의 근본 원인
지연 급등으로 인한 불필요한 재전송 Spurious RTO from delay spikes
원인 ID rt-spurious-delay · 주 담당 외부·외부 · 함께 인프라팀·서버 인프라, 게임개발팀·클라이언트 개발
그림과 실험이 있는 원본 카드로 열기 →
패킷은 사라지지 않고 잠깐 아주 늦게 도착했을 뿐인데, 그 지연이 RTO보다 길면 보내는 쪽이 손실로 판단해 재전송합니다.
왜 버퍼블로트, 와이파이 절전, 모바일 무선 상태 전환, 가상 머신 일시 정지로 순간 지연이 수백 ms → 그러면 RTO가 먼저 만료되어 재전송, 원본도 곧 도착(받는 쪽은 중복으로 받음) → 화면에서는 멈춤·몰아치기는 지연 급등 자체 때문. 불필요한 재전송은 멈춤을 거의 늘리지 않고 재전송 지표만 올려 손실로 오해받음
증상 멈춤 , 몰아치기 , 입력 지연
요인 지연, 지터
누가 겪나 나만, 서버 전체
언제 가끔 무작위로, 가만히 있다가
담당 주 담당 외부·외부 · 함께 인프라팀·서버 인프라, 게임개발팀·클라이언트 개발
게임개발팀 할 일 안드로이드 10 이상 클라이언트는 게임 중 저지연 와이파이 모드(WIFI_MODE_FULL_LOW_LATENCY 와이파이 잠금, 화면이 켜져 있고 게임이 앞에 있을 때만 적용)를 요청해 절전으로 생기는 지연 급등 줄이기.
인프라팀 할 일 버스트형 인스턴스 피하기, RTO 최소값을 너무 낮추지 않기, F-RTO·타임스탬프 유지(tcp_frto, tcp_timestamps), 재전송 지표는 nstat의 TCPSpuriousRTOs·TCPDSACKRecv와 함께 봐서 손실로 오해하지 않기.
외부 할 일 지연 급등 자체를 줄이도록 유저에게 공유기 SQM 사용, 와이파이 절전 끄기 안내.
수치 감각 리눅스는 F-RTO로 불필요한 RTO를 감지하고 전송량 축소를 되돌리기도 합니다. nstat의 TCPSpuriousRTOs(불필요한 RTO로 판정한 횟수)와 TCPDSACKRecv(받는 쪽이 “이미 받은 것”이라고 알려 온 횟수)로 확인합니다.
그래프에서는 가끔 무작위로 튐 · RTT(핑), 불필요한 RTO 수
확인할 곳 nstat을 1분 간격으로 실행해 TcpExtTCPTimeouts(RTO 만료), TcpExtTCPSpuriousRTOs, TcpExtTCPDSACKRecv, TcpExtTCPLostRetransmit의 증가분을 함께 봄. 패킷 캡처가 있으면 Wireshark 필터 tcp.analysis.spurious_retransmission을 씀 이러면 맞음 RTO가 늘 때 TcpExtTCPSpuriousRTOs나 TcpExtTCPDSACKRecv도 함께 늘고, 같은 시각에 RTT가 수백 ms로 튐. 받는 쪽 캡처에 원본과 재전송이 모두 도착해 있음 이러면 아님 TcpExtTCPSpuriousRTOs·DSACK은 그대로인데 TcpExtTCPLostRetransmit(다시 보낸 것까지 또 잃음)이 늘면 실제 손실. RTT는 튀지 않는데 DSACK만 꾸준히 많으면 “순서 뒤바뀜으로 인한 불필요한 빠른 재전송” 확인 수단 인프라 도구로 확인(게임 코드 불필요)
출처 RFC 5682: Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP IETF F-RTO: RTO 뒤에 온 ACK로 불필요한 RTO였는지 가려냄 RFC 3481: TCP over Second (2.5G) and Third (3G) Generation Wireless Networks IETF 모바일망의 지연 급등(핸드오버, 링크 복구 등)이 불필요한 TCP 타임아웃·재전송과 혼잡 윈도우 축소를 일으킴 RFC 2883: An Extension to the Selective Acknowledgement (SACK) Option for TCP IETF DSACK: 받는 쪽이 중복 수신을 알려 보내는 쪽이 불필요한 재전송을 알 수 있음 SNMP counter Linux kernel TcpExtTCPSpuriousRTOs(F-RTO가 감지한 불필요한 RTO), TcpExtTCPDSACKRecv(받은 DSACK 수), TcpExtTCPLostRetransmit(다시 보낸 패킷을 또 잃었다고 SACK이 알려 온 수) IP Sysctl Linux kernel tcp_frto 기본 켜짐(RTT가 흔들리는 무선망에 유리), tcp_timestamps 기본 1 RFC 6298: Computing TCP's Retransmission Timer IETF 불필요한 재전송을 막으려면 큰 최소 RTO가 필요하다는 근거(최소 1초 권고) WifiManager Android (Google) WIFI_MODE_FULL_LOW_LATENCY(API 29, 안드로이드 10): AP에 연결되어 있고 화면이 켜져 있고 앱이 앞에 있을 때만 적용되는 저지연 와이파이 잠금 net/ipv4/proc.c Linux kernel nstat에 나오는 카운터 이름 TCPTimeouts·TCPSpuriousRTOs·TCPDSACKRecv·TCPLostRetransmit net/ipv4/tcp_timer.c Linux kernel TCPTimeouts는 재전송 타이머(RTO)가 만료될 때 증가 nstat(8) — Linux manual page iproute2 nstat은 기본으로 이전 실행 이후의 증가분을 보여 줌 Display Filter Reference: Transmission Control Protocol Wireshark tcp.analysis.spurious_retransmission 표시 필터
함께 보면 좋은 원인
같은 층: TCP 재전송의 근본 원인
같은 증상(멈춤)의 다른 층 원인
그림과 실험이 있는 원본 카드 보기