접속 요청이 접속 대기열(backlog) 넘침이나 방화벽 차단으로 사라지면, 클라이언트 OS가 1초 뒤부터 간격을 늘려 가며 다시 보냅니다.
왜 점검 직후 접속 폭주로 서버 접속 대기열이 넘치거나, 방화벽·DDoS 방어가 SYN을 버림 → 그러면 클라이언트 OS가 1초 뒤부터 정해진 간격으로 SYN 재전송(예전 리눅스는 1초 → 2초 → 4초) → 화면에서는 접속 버튼 뒤 1초, 3초처럼 초 단위로 딱 떨어지게 늦고 계속 실패하면 접속 불가·무한 로딩
주 담당 게임개발팀·서버 개발 · 함께 인프라팀·서버 인프라, 인프라팀·네트워크 인프라, 게임개발팀·클라이언트 개발
게임개발팀 할 일
서버: listen의 backlog 인자 늘리기(somaxconn과 함께), 게임 서버가 accept를 제때 부르게 하기, 로그인 대기열 시스템. 클라이언트: 접속 재시도 간격 늘리기(무작위로 분산).
인프라팀 할 일
서버 장비·OS: 서버 접속 대기열 넘침은 nstat의 TcpExtListenOverflows·TcpExtListenDrops와 로그의 “Possible SYN flooding” 경고로 확인, somaxconn 늘리기(listen 인자와 함께), SYN 쿠키. 네트워크: 방화벽·DDoS 방어의 SYN 제한 완화.
수치 감각
리눅스(안드로이드 포함) 첫 SYN 재전송은 1초 뒤입니다. 예전 커널은 이후 간격을 두 배씩 늘려 1, 3, 7, 15초 …에 다시 보냅니다. 6.5 이상은 1, 2, 3, 4, 5초에 다섯 번 다시 보낸 뒤 두 배씩(7, 11, 19초 …) 늘립니다(tcp_syn_linear_timeouts=4). 안드로이드 폰은 OS를 업데이트해도 출시 때의 커널을 계속 쓰는 경우가 많아, 같은 안드로이드 버전이라도 기기마다 다를 수 있습니다. 어느 쪽이든 모두 실패하면 약 2분 뒤 포기합니다. 윈도우는 버전과 설정에 따라 1초 또는 3초부터 늘어나고 다시 보내는 횟수가 2~4번이라 20~30초 만에 포기합니다(그 PC의 값은 netsh int tcp show global의 Max SYN Retransmissions로 확인).
그래프에서는
접속·점검 직후 폭증 · 접속 시도 수, 접속 대기열 넘침 수
확인할 곳
서버의 nstat에서 TcpExtListenOverflows·TcpExtListenDrops와 dmesg의 “Possible SYN flooding on port” 경고를 보고 ss -lnt로 접속 대기 소켓의 Recv-Q(accept를 기다리는 연결 수)가 Send-Q(backlog 한도)에 닿는지 봄. 서버 쪽 캡처로 SYN이 도착하는지, SYN-ACK를 돌려보내는지 확인함
이러면 맞음
점검 직후 접속 폭주 때 TcpExtListenOverflows가 늘고 Recv-Q가 Send-Q에 붙어 있음. 캡처에서 같은 클라이언트의 SYN이 초 단위 간격으로 다시 오는데 서버가 응답하지 않음
이러면 아님
SYN이 서버까지 오지 않고 서버 카운터도 그대로면 앞단 방화벽·DDoS 방어가 버린 것이니 그 장비의 SYN 제한·드롭 로그를 봄. 서버가 SYN-ACK를 보냈는데도 접속이 늦으면 돌아가는 방향의 손실
확인 수단
인프라 도구로 확인(게임 코드 불필요)
출처
include/net/tcp.hLinux kernel 첫 RTO TCP_TIMEOUT_INIT = 1초(RFC 6298의 초기값)
IP SysctlLinux kernel tcp_syn_retries 기본 6, tcp_syn_linear_timeouts 기본 4(SYN RTO 1, 1, 1, 1, 1, 2, 4 …), 마지막 재전송 67초·포기 131초, somaxconn 기본 4096, tcp_syncookies 기본 1