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

게임 렉 백서 › TCP 재전송의 근본 원인

연결 도중 NAT·로드밸런서 매핑 만료 NAT / load balancer mapping expired mid-connection

원인 ID rt-mapping · 주 담당 게임개발팀·클라이언트 개발 · 함께 게임개발팀·서버 개발, 인프라팀·네트워크 인프라, 인프라팀·서버 인프라

그림과 실험이 있는 원본 카드로 열기 →

유휴 연결의 매핑(이 연결을 어디로 전달할지 기록한 항목)을 중간 장비가 지우면, 다음에 보내는 패킷은 전달되지 못합니다. 재전송만 반복하다 접속이 끊기거나, 장비가 연결 거부(RST)를 돌려보내 곧바로 끊깁니다.

왜 한동안 오가는 패킷이 없는 연결(자리 비움, 로비) → 그러면 공유기 NAT·통신사 CGNAT·방화벽·로드밸런서·클라우드 보안 그룹이 유휴 매핑을 삭제 → 화면에서는 다시 움직이는 순간 재전송이 이어지다 접속 끊김, 또는 바로 접속 끊김

증상
접속 끊김, 멈춤
요인
손실
누가 겪나
나만, 특정 지역·통신사
언제
가만히 있다가
담당
주 담당 게임개발팀·클라이언트 개발 · 함께 게임개발팀·서버 개발, 인프라팀·네트워크 인프라, 인프라팀·서버 인프라
게임개발팀 할 일
클라이언트: 가장 짧은 유휴 타임아웃의 절반 이하 간격으로 하트비트 보내기(유저 공유기·통신사 CGNAT의 매핑은 안에서 나가는 패킷으로만 확실히 갱신되고 타임아웃은 우리가 못 바꾸므로 클라이언트가 보냄), 끊기면 자동 재접속. 서버: 하트비트에 응답하고 일정 시간 못 받으면 연결을 먼저 정리(TCP keepalive 간격 줄이기(TCP_KEEPIDLE 등 소켓 옵션), TCP_USER_TIMEOUT으로 빨리 감지), 세션 토큰으로 이어 받기.
인프라팀 할 일
네트워크: 경로에 있는 방화벽·로드밸런서의 유휴 타임아웃을 모아 게임팀에 공유, 우리 방화벽·로드밸런서는 필요하면 늘리기. 서버 장비·OS: 클라우드 보안 그룹의 연결 추적 시간을 확인해 게임팀에 공유.
수치 감각
TCP 매핑을 유지하는 시간은 장비마다 수 분에서 몇 시간까지 제각각입니다. 클라우드 보안 그룹이 연결을 추적하는 설정이면 AWS Nitro v6 인스턴스 유형은 기본 350초 뒤 추적 항목을 지웁니다(그 밖의 유형은 5일, “클라우드 보안 그룹의 연결 추적 만료” 항목 참고). 리눅스 TCP keepalive는 기본값이 “2시간 유휴 상태면 확인”이라 대부분의 장비보다 늦습니다.
그래프에서는
연결이 한꺼번에 끊김 · 끊김 수, 끊기기 전 유휴 시간
확인할 곳
끊긴 연결의 마지막 몇 분을 서버 쪽 패킷 캡처로 보고 살아 있는 연결은 ss -ti의 lastsnd·lastrcv(마지막으로 보내고 받은 뒤 지난 ms)로 유휴 시간을 봄. nstat의 TcpExtTCPAbortOnTimeout(타이머가 다 돼 연결을 포기한 수)도 함께 봄
이러면 맞음
끊긴 연결마다 직전 유휴 시간이 비슷한 값(경로에 있는 장비의 유휴 타임아웃, 예: AWS Nitro v6 인스턴스 보안 그룹의 350초)을 넘었고 유휴 뒤 첫 패킷부터 ACK 없이 재전송만 이어지다 포기하거나 곧바로 RST가 돌아옴
이러면 아님
유휴 시간과 상관없이 게임 중에도 끊기면 다른 원인(“경로 변경·ECMP 불량 경로”, “방화벽·연결 추적의 폐기”). 하트비트가 가장 짧은 유휴 타임아웃의 절반 이하 간격으로 오가는 연결이면 이 원인에서 뺌
확인 수단
인프라 도구로 확인(게임 코드 불필요)

출처

  1. RFC 5382: NAT Behavioral Requirements for TCP IETF
    TCP NAT의 연결 유휴 타임아웃은 2시간 4분 이상이어야 한다는 권고(장비가 유휴 세션을 먼저 지울 수 있음을 전제)
  2. RFC 4787: Network Address Translation (NAT) Behavioral Requirements for Unicast UDP IETF
    NAT 매핑은 안에서 나가는 패킷으로 갱신되어야 하고(REQ-6), 밖에서 들어오는 패킷의 갱신은 선택 사항(UDP 기준)
  3. Amazon EC2 security group connection tracking AWS
    TCP 유휴 추적 타임아웃 기본값은 Nitro v6 인스턴스 유형 350초, 그 밖의 유형 432,000초(5일). 5분보다 짧은 간격의 keepalive 권고
  4. IP Sysctl Linux kernel
    tcp_keepalive_time 기본 2시간
  5. tcp(7) — Linux manual page Linux man-pages
    TCP_KEEPIDLE(keepalive를 시작하기 전 유휴 시간), TCP_USER_TIMEOUT(확인받지 못한 데이터를 기다리다 연결을 닫는 시간)
  6. RFC 5482: TCP User Timeout Option IETF
    TCP 사용자 타임아웃: 보낸 데이터가 확인받지 못한 채 얼마나 지나면 연결을 닫을지
  7. ss(8) — Linux manual page iproute2
    ss -i의 lastsnd·lastrcv: 마지막으로 보내고 받은 뒤 지난 시간(ms)
  8. SNMP counter Linux kernel
    TcpExtTCPAbortOnTimeout: TCP 타이머가 다 돼 RST 없이 연결을 포기한 수

함께 보면 좋은 원인

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

같은 증상(접속 끊김)의 다른 층 원인

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