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

ゲームラグ白書 › 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接続が残っており、そのアカウントの再接続が「すでに接続中」で拒否されている
該当しない場合
長時間無通信の接続がないのに「すでに接続中」が出るなら、ゲームサーバーのセッション整理のコード側
確認手段
インフラのツールで確認(ゲームコード不要)

出典

  1. tcp(7) — Linux manual page Linux man-pages
    7,200秒アイドルの後に75秒間隔でプローブ9回(約11分追加)、SO_KEEPALIVEを有効にしたソケットにのみ適用、TCP_KEEPIDLE・TCP_USER_TIMEOUT
  2. RFC 9293: Transmission Control Protocol (TCP) IETF
    keepaliveはデフォルトで無効でなければならず、アイドル間隔のデフォルト値は2時間以上
  3. SO_KEEPALIVE socket option Microsoft
    WindowsのTCP keepaliveのデフォルトタイムアウトは2時間
  4. ss(8) — Linux manual page iproute2
    -iのlastrcv(最終受信からの経過ms)、-oのtimer:(keepalive,…)

あわせて読みたい原因

同じ層:L8 ソケットとプロトコル

同じ症状(接続不可・無限ロード)を起こすほかの層の原因

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