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

게임 렉 백서 › L8 소켓과 프로토콜

느린 클라이언트로 인한 블로킹 전송 Blocking send on a full socket

원인 ID sk-block-send · 주 담당 게임개발팀·서버 개발

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

회선이 느린 한 명의 송신 버퍼가 가득 찼는데 블로킹 방식(버퍼에 여유가 생길 때까지 호출이 반환되지 않는 전송)으로 보내면, 서버 스레드가 그 한 명을 기다립니다.

왜 느린 클라이언트의 송신 버퍼가 가득 → 그러면 블로킹 전송이라 서버 스레드가 버퍼에 여유가 생길 때까지 대기 → 화면에서는 그 스레드가 맡은 모두가 멈춤·슬로우모션

증상
멈춤, 슬로우모션
요인
정체
누가 겪나
특정 장소·채널, 서버 전체
언제
가끔 무작위로, 사람이 몰릴 때
담당
주 담당 게임개발팀·서버 개발
게임개발팀 할 일
논블로킹 전송, 클라이언트별 송신 대기열 상한, 오래된 업데이트 버리기.
그래프에서는
가끔 무작위로 튐 · 서버 틱 시간, 연결별 Send-Q
확인할 곳
ss -tn으로 연결별 Send-Q(ACK를 받지 못했거나 아직 못 보낸 바이트)가 송신 버퍼만큼 찬 연결을 찾고, 틱이 튄 순간 게임 서버의 스레드 덤프(스택)에서 send 호출에 멈춘 스레드가 있는지 봄
이러면 맞음
Send-Q가 가득 찬 느린 연결이 있을 때 그 연결을 맡은 스레드가 send에서 멈춰 있고, 같은 스레드가 맡은 사람들만 함께 멈춤
이러면 아님
멈춘 스레드가 send 밖(락, DB 호출)에서 기다리면 “락 경합”, “게임 스레드의 동기 호출”
확인 수단
인프라 도구로 확인(게임 코드 불필요)

출처

  1. send(2) — Linux manual page Linux man-pages
    송신 버퍼에 자리가 없으면 send()가 블록되고 논블로킹 모드면 EAGAIN으로 바로 돌아옴
  2. send function (winsock2.h) Microsoft
    Winsock도 버퍼 공간이 없으면 논블로킹 모드가 아닌 한 send가 블록
  3. net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel
    ss의 Recv-Q·Send-Q 값: 리슨 소켓은 accept를 기다리는 접속 수와 backlog 한도, 연결된 소켓은 앱이 아직 안 읽은 바이트와 ACK를 받지 못한 송신 바이트

함께 보면 좋은 원인

같은 층: L8 소켓과 프로토콜

같은 증상(멈춤)의 다른 층 원인

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