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

ゲームラグ白書 › L8 ソケットとプロトコル

遅いクライアントによるブロッキング送信 Blocking send on a full socket

原因ID sk-block-send · 主担当 ゲーム開発チーム・サーバー開発

図と実験のあるメインページでこのカードを開く →

回線の遅い1人の送信バッファが満杯なのに、ブロッキング方式(バッファに空きができるまで呼び出しが戻らない送信)で送ると、サーバーのスレッドがその1人を待ちます。

なぜ 遅いクライアントの送信バッファが満杯 → すると ブロッキング送信のため、サーバーのスレッドがバッファに空きができるまで待機 → 画面では そのスレッドが担当する全員がフリーズ・スローモーション

症状
フリーズ, スローモーション
要因
ストール
誰に起きるか
特定の場所・チャンネル, サーバー全体
いつ
ときどきランダムに, 人が集中したとき
担当
主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応
ノンブロッキング送信、クライアントごとの送信キューの上限、古い更新の破棄。
グラフでは
不定期なスパイク · サーバーのティック時間、接続ごとの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 ソケットとプロトコル

同じ症状(フリーズ)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る