1:49 · boss fight · receive queue · zero window · send queue

클라가 느리면 서버도 느려진다

이 영상에 나오는 용어 15개.

공유 브로드캐스트 버퍼
같은 패킷을 여러 세션에 보낼 때 복사 대신 함께 참조하는 버퍼다. 참조하는 세션이 모두 보내야 해제되므로 느린 세션 하나가 메모리를 붙잡는다.
논블로킹 send
버퍼가 차도 기다리지 않고 바로 반환하는 전송 방식이다. 로직 스레드가 느린 클라이언트 때문에 멈추지 않게 해 준다.
메인 스레드
클라이언트의 게임 로직과 렌더를 돌리는 스레드다. 프레임마다 수신 큐에서 정해진 개수만큼 패킷을 꺼내 처리한다.
백프레셔 (backpressure)
받는 쪽이 느릴 때 그 압력이 보내는 쪽으로 거슬러 전달되는 현상이다. 이 영상에서는 클라이언트 수신 큐에서 시작해 서버 앱 송신 큐까지 전달된다.
수신 스레드
클라이언트에서 소켓 읽기만 전담하는 스레드다. 렌더가 느려도 커널 수신 버퍼를 계속 비워 서버 쪽으로 압력이 가지 않게 한다.
수신 큐
수신 스레드가 받은 패킷을 메인 스레드가 꺼내 갈 때까지 담아 두는 앱 메모리 안의 큐다.
앱 송신 큐 (세션 송신 큐)
서버가 세션별로 두는, 커널에 아직 넘기지 못한 데이터의 대기열이다. 느린 클라이언트일수록 커지고, 상한에 닿으면 연결을 끊는 경우가 많다.
프레임당 처리 예산
한 프레임에 처리할 패킷 수의 한도다. 프레임 시간이 길어지는 것을 막는 대신 남은 패킷은 다음 프레임으로 넘어간다.
EAGAIN
논블로킹 소켓에서 커널 송신 버퍼가 가득 차 send()가 지금은 쓸 수 없다고 돌려주는 오류 코드다. 앱은 데이터를 자기 큐에 두고 나중에 다시 보내야 한다.
FPS
초당 프레임 수다. 메인 스레드가 프레임마다 패킷을 꺼내므로 FPS가 떨어지면 초당 처리량도 같이 떨어진다.
GC 정지
가비지 컬렉터가 메모리를 정리하는 동안 스레드가 멈추는 현상이다. 수신 경로에서 할당이 많으면 자주 일어난다.
IOCP
Windows의 비동기 I/O 완료 통지 방식이다. 전송 요청을 걸어 두면 대기 중인 바이트가 쌓이므로 여기에도 상한이 필요하다.
Send-Q
ss 출력에서 연결별로 커널 송신 버퍼에 남아 상대의 ACK를 기다리는 바이트 수다. 특정 연결만 크면 그 클라이언트가 느리게 받아가고 있다는 신호다.
SO_RCVBUF / SO_SNDBUF
소켓의 커널 수신 버퍼와 송신 버퍼 크기 옵션이다. 앱이 읽지 않으면 수신 버퍼가, 상대가 받지 않으면 송신 버퍼가 찬다.
Zero Window
TCP 수신 측이 ACK에 수신 윈도우 0을 알려 더 받을 수 없다고 알리는 상태다. 송신 측 커널은 윈도우가 다시 열릴 때까지 전송을 멈춘다.