ゲームラグ白書 › L8 ソケットとプロトコル
RSTによる強制終了で最後のデータが消失 SO_LINGER, abrupt RST
原因ID sk-linger · 主担当 ゲーム開発チーム・サーバー開発
図と実験のあるメインページでこのカードを開く →
サーバーが接続を急に切ると、最後に送った案内や保存完了の通知が失われます。
なぜ サーバーが接続を強制終了(RST)で閉じる。SO_LINGERを0秒にしたり、受信したデータを読み切らずに閉じたりすると起きる → すると まだ送信中だったキックの理由や最後のデータが破棄される → 画面では 理由の分からない「不明なエラーにより接続が切断されました」
- 症状
- 切断
- 要因
- パケットロス
- 誰に起きるか
- 自分だけ
- いつ
- ときどきランダムに
- 担当
- 主担当 ゲーム開発チーム・サーバー開発
- ゲーム開発チームの対応
- 理由を送った後に送信方向だけを先に閉じ(shutdown)、相手が閉じるまで受信したデータを最後まで読んでから閉じる、SO_LINGERの0秒を避ける。
- グラフでは
- 不定期なスパイク · RSTで終わった接続の数
- 確認箇所
- nstat -azのTcpExtTCPAbortOnData(送るデータが残ったままRSTで閉じた、SO_LINGER 0秒)・TcpExtTCPAbortOnClose(読んでいないデータが残ったまま閉じた)の増加量を確認し、切断の瞬間にサーバー側のパケットキャプチャでFINの代わりにRSTが出ているかを確認
- 該当する場合
- 「不明なエラーにより接続が切断されました」の報告時刻にサーバーがRSTを送っており、AbortOnData・AbortOnCloseが増えている
- 該当しない場合
- サーバーがFINで正常に終了しているのに理由が表示されなければ、クライアントの終了処理側
- 確認手段
- インフラのツールで確認(ゲームコード不要)
出典
- closesocket function (winsock.h) Microsoft
SO_LINGERを有効にして時間を0にすると、接続を即座にリセットする強制終了になり、送れなかったデータは失われる - RFC 9293: Transmission Control Protocol (TCP) IETF
受信したデータが残ったまま閉じると、データの消失を知らせるためにRSTを送る - Graceful Shutdown, Linger Options, and Socket Closure Microsoft
shutdownで送信だけを先に閉じ、相手の終了通知を受け取ってからソケットを閉じる手順 - SNMP counter Linux kernel
TcpExtTCPAbortOnData:SO_LINGER 0秒などで、送るデータが残ったままRSTで閉じた、TcpExtTCPAbortOnClose:読んでいないデータが残ったまま閉じてRSTを送った
あわせて読みたい原因
同じ層:L8 ソケットとプロトコル
同じ症状(切断)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る