ゲームラグ白書 › L8 ソケットとプロトコル
keepaliveのデフォルト2時間 TCP keepalive defaults
原因ID sk-keepalive · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
図と実験のあるメインページでこのカードを開く →
相手が終了の合図なしに消えると、TCPはかなり時間がたってから検知します。keepalive(アイドル接続が生きているかを確認するTCPの機能)はデフォルトで無効で、有効にしても2時間アイドル状態が続かないと確認を始めません。
なぜ クライアントが電源断や回線断で、終了の合図なしに消える → すると サーバーは接続が生きているとみなす(keepaliveのデフォルトは7,200秒。送信中のデータがあれば再送をあきらめるまで約15分) → 画面では キャラクターがゴーストとして残り、再接続すると「すでに接続中」エラー
- 症状
- 接続不可・無限ロード, 表示されない・ゴースト
- 要因
- パケットロス
- 誰に起きるか
- 自分だけ
- いつ
- しばらく放置した後, 接続直後・メンテ明け
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
- ゲーム開発チームの対応
- サーバー:ハートビートに応答し、一定時間受信がなければ接続を先に整理(TCP_KEEPIDLE・TCP_USER_TIMEOUTの調整)、再接続したらセッショントークンで既存のセッションを置き換えて引き継ぐ。クライアント:ゲームレベルのハートビートを数秒〜数十秒間隔(最も短いアイドルタイムアウトの半分以下)で送る、切れたら自動で再接続。
- インフラチームの対応
- コードで個別に設定していないソケットのために、カーネルのデフォルト値(tcp_keepalive_timeなど)を下げる(SO_KEEPALIVEを有効にしたソケットにのみ適用)。
- 数値の目安
- Linuxのデフォルトでは、7,200秒アイドル状態が続くと確認を始め、75秒間隔でプローブを9回送り、最後まで応答がなければ接続を切ります。合計で約2時間11分です。Windowsもデフォルトでは、2時間アイドル状態が続かないと確認を始めません。
- グラフでは
- 一部だけ高い · 接続ごとの最終受信からの経過時間
- 確認箇所
- ss -tnoiで接続ごとのlastrcv(最終受信からの経過ms)とkeepaliveタイマー(timer:(keepalive,…))を確認し、ゲームサーバーが「すでに接続中」で拒否した記録と突き合わせる
- 該当する場合
- lastrcvが数分〜数時間のESTABLISHED接続が残っており、そのアカウントの再接続が「すでに接続中」で拒否されている
- 該当しない場合
- 長時間無通信の接続がないのに「すでに接続中」が出るなら、ゲームサーバーのセッション整理のコード側
- 確認手段
- インフラのツールで確認(ゲームコード不要)
出典
- tcp(7) — Linux manual page Linux man-pages
7,200秒アイドルの後に75秒間隔でプローブ9回(約11分追加)、SO_KEEPALIVEを有効にしたソケットにのみ適用、TCP_KEEPIDLE・TCP_USER_TIMEOUT - RFC 9293: Transmission Control Protocol (TCP) IETF
keepaliveはデフォルトで無効でなければならず、アイドル間隔のデフォルト値は2時間以上 - SO_KEEPALIVE socket option Microsoft
WindowsのTCP keepaliveのデフォルトタイムアウトは2時間 - ss(8) — Linux manual page iproute2
-iのlastrcv(最終受信からの経過ms)、-oのtimer:(keepalive,…)
あわせて読みたい原因
同じ層:L8 ソケットとプロトコル
同じ症状(接続不可・無限ロード)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る