ゲームラグ白書 › L8 ソケットとプロトコル
TCPのHOLブロッキング Head-of-line blocking
原因ID sk-hol · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
図と実験のあるメインページでこのカードを開く →
TCPは順序を守るため、失われたパケットを1つ受け取り直すまで、後から届いたパケットをゲームに渡しません。
なぜ パケットが1つ消失 → すると 後続のパケットは届いているが、受信バッファで待機 → 画面では 止まった後に一気に解放されて早送り
- 症状
- フリーズ, 早送り
- 要因
- パケットロス, ストール
- 誰に起きるか
- 自分だけ
- いつ
- ときどきランダムに
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
- ゲーム開発チームの対応
- サーバー:リアルタイムの位置はUDP、どうしても必要なものだけ信頼性のある送信、ストリームを複数に分ける。クライアント:サーバーと同じ方式(UDP、チャネル分離)にネットワーク処理を変更。
- 数値の目安
- パケットを1つ失うと最低でも往復時間+α、再送パケットまで失うと数百ms〜数秒止まります。
- グラフでは
- 途切れた後にまとめて到着 · 接続ごとの受信量、再送数
- 確認箇所
- サーバー側のパケットキャプチャ(tcpdump・Wireshark)で、そのユーザーの接続の再送パケットとその前後の空白を確認し、サーバー全体はnstat -azでTcpRetransSegsの増加量を確認
- 該当する場合
- 止まった区間がパケット1つの再送から始まり、再送パケットが届いた直後にたまっていたデータが一気に処理される(受信量が0の状態から急増)
- 該当しない場合
- UDPで通信するゲームなら該当しない。再送がないのに止まるなら、サーバーのティック側(「ティックバジェット超過」)を確認
- 確認手段
- インフラのツールで確認(ゲームコード不要)
出典
- RFC 9293: Transmission Control Protocol (TCP) IETF
TCPは信頼性があり、順序を守るバイトストリームのサービス - RFC 5681: TCP Congestion Control IETF
重複ACK 3つでロスを検知して高速再送、そうでなければ再送タイマーを待つ - RFC 6298: Computing TCP's Retransmission Timer IETF
再送タイマーが満了するたびに2倍に延ばすバックオフ - net/ipv4/proc.c (Linux v6.12) Linux kernel
nstatが表示するカウンター名:TcpグループのRetransSegs(再送したセグメント数)
あわせて読みたい原因
同じ層:L8 ソケットとプロトコル
同じ症状(フリーズ)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る