게임처럼 작은 패킷을 드문드문 보내면 “뒤따르는 패킷 3개”가 모이기 전에 RTO가 먼저 옵니다. 대용량 전송보다 같은 손실에 훨씬 오래 멈춥니다.
왜 패킷 간격이 100ms 안팎이라 아직 ACK를 받지 못한(in-flight) 패킷이 몇 개 없음 → 그러면 중복 ACK 3개가 모이려면 300ms 넘게 걸려 RTO(핑 + 200ms)가 먼저 발동, 연속 손실이면 두 배씩 → 화면에서는 손실 한 번에 0.3초 안팎 멈춤, 다시 보낸 것까지 잃으면 1초 가까이 멈춘 뒤 몰아치기
서버: TCP_NODELAY 켜기(Nagle이 켜져 있으면 RACK이 판단에 쓸 뒤따르는 패킷이 없음), 실시간 패킷은 UDP 위의 자체 재전송으로. 클라이언트: TCP_NODELAY 켜기, 실시간 패킷은 서버와 같은 방식(UDP)으로.
인프라팀 할 일
RACK-TLP 사용(최신 리눅스 기본), tcp_thin_linear_timeouts로 연속 RTO가 두 배로 늘지 않게.
수치 감각
패킷 간격 100ms, 핑 60ms면 빠른 재전송까지 약 360ms(뒤 패킷 3개가 도착하고 그 확인이 돌아올 때까지), RTO는 약 260ms. RACK을 쓰면 다음 패킷의 확인이 돌아오는 약 160ms에 바로 다시 보냅니다. 패킷 간격이 200ms를 넘으면 RACK도 RTO보다 빠르지 않습니다.
그래프에서는
끊겼다가 몰아서 · 연결별 수신량, RTO 만료 수
확인할 곳
nstat의 TcpExtTCPTimeouts(RTO 만료)·TcpExtTCPFastRetrans(빠른 재전송)·TcpExtTCPLossProbes·TcpExtTCPLossProbeRecovery(TLP) 증가분을 비교하고, 게임 연결을 ss -ti로 보아 rto·backoff를 봄. 서버의 net.ipv4.tcp_recovery·tcp_early_retrans·tcp_sack 값도 확인함
이러면 맞음
재전송 가운데 RTO 만료가 빠른 재전송보다 많고 게임 연결에서 backoff가 0보다 큰 경우(RTO를 겪는 중)가 자주 보임. 멈춘 동안 받은 양이 0이다가 복구되면 한꺼번에 몰려옴
이러면 아님
같은 서버의 대용량 전송도 똑같이 오래 멈추면 연결 모양과 상관없는 손실 문제. SACK·타임스탬프가 빠진 연결에 몰리면 “중간 장비의 TCP 옵션 제거”
확인 수단
인프라 도구로 확인(게임 코드 불필요)
더 알아보기
리눅스에는 예전에 thin stream용 중복 ACK 1개 재전송 옵션(tcp_thin_dupack)도 있었지만 2017년에 없어졌고, 지금은 RACK이 그 역할을 대신합니다. Nagle이 켜져 있으면(TCP_NODELAY 꺼짐) 잃은 패킷의 확인을 기다리는 동안 새 패킷도 보내지 않습니다. RACK이 판단에 쓸 뒤따르는 패킷이 없으니 RTO까지 기다립니다.
출처
Thin-streams and TCPLinux kernel 게임처럼 드문드문 보내는 thin stream은 빠른 재전송이 잘 작동하지 않아 긴 타임아웃에 기댐, 아직 ACK를 받지 못한 패킷(in-flight) 4개 미만이 기준