ゲームラグ白書 テキスト版
オンラインゲームで画面がカクつく、キャラがワープする、接続が切れる。そんなラグの原因228件を、自分の画面からサーバーのDBまで層ごとに整理したテキスト版。原因ごとに症状、担当チーム、数値、出典を掲載。
図と、実際に操作できる実験を含むメインページはゲームラグ白書 です。この版は同じ原因・用語・出典を、JavaScriptなしで1ページで読めるようにまとめたものです。原因ごとの個別ページ(c/ID.html)もあります。Markdownの1ファイルにまとめたものはllms-full.txt にあります。
目次
症状から探す
ラグは次の4つの要因から始まります: 遅延 (距離、キュー、処理時間のために、すべてのパケットが一様に遅れて届きます。) ジッター (平均は問題なくても、あるパケットは早く、あるパケットは遅れて届きます。Wi-Fi、混雑した回線、高負荷のCPUが原因になります。) パケットロス (あふれたキュー、電波干渉、故障した機器がパケットを破棄します。回線の瞬断も、連続したパケットロスです。) ストール (サーバーのティックが遅れたり止まったり(GC、ロック、同期呼び出し、過負荷)、自分のPCのフレームが止まったりします。回線に問題がなくても起きます。)
カクつき (原因60件): 動きが滑らかでなく、短く止まっては動くのを繰り返します。ワープ (原因47件): キャラクターが途中の移動なしに、離れた位置へ一瞬で移ります。引き戻し (原因14件): 自分のキャラクターが前に進んでいたのに、今通ってきた位置へ引き戻されます。早送り (原因36件): 止まっていた画面が動き出すと同時に、たまっていた動き・ヒット・ダメージが一気に早回しで流れます。スローモーション (原因24件): すべてがゆっくり動きます。スキルの発動やモンスターの移動が間延びして見えます。サーバーの設計によっては、速度はそのままでカクつき・ワープとして現れることもあります。入力遅延 (原因76件): 押してから結果が出るまでに時間がかかります。画面そのものは滑らかな場合もあります。フリーズ (原因67件): 画面内のすべてが少しの間(0.5秒〜数秒)止まってから、また動き出します。不発・ロールバック (原因36件): 確かにやったはずの行動がなかったことになるか、結果がしばらく経ってから覆ります。切断 (原因51件): プレイ中に接続が切れ、ログイン画面や再接続の画面に戻されます。接続不可・無限ロード (原因45件): ゲームに入れない、またはロード・入場画面で止まったままになります。表示されない・ゴースト (原因20件): いるはずのNPC・モンスター・プレイヤーが自分の画面にだけいない、またはすでに消えたオブジェクトが自分の画面にだけ残っています。
担当チームと担当コード
コード チーム 担当 範囲
cliゲーム開発チーム クライアント開発 ゲームクライアントのコード:フレーム・GC・ロード、補間・外挿・予測、クライアントのネットワーク処理(ハートビート送信・自動再接続を含む)
srvゲーム開発チーム サーバー開発 ゲームサーバーのコード:ティック・スレッド・ロック、同期設計、接続処理(acceptループ・listenの引数)、ハートビートへの応答・切れた接続の後始末、ソケットオプション、クエリ・トランザクション設計
netインフラチーム ネットワークインフラ 回線とデータセンターのネットワーク機器(スイッチ・ルーター・ファイアウォール・ロードバランサー・DDoS対策)、クラウドのネットワークACL・VPCルーティング・ロードバランサー、通信事業者・ピアリング
sysインフラチーム サーバーインフラ サーバー機器・クラウドインスタンス(セキュリティグループ・接続追跡を含む)、OS・カーネル設定、NIC、デプロイ・監視環境
dbaインフラチーム DBインフラ DBサーバー・ストレージ、DBの設定・レプリケーション・バックアップ、キャッシュサーバー
ext外部 外部 ユーザーのPC・家庭内ネットワーク、通信事業者の区間(自社の契約外)、クラウド事業者。直接は直せないため、案内・依頼・回避策で対応
L1 クライアントのゲームプロセス
原因16件 · メインページの章
ID cg-hitch · 主担当 ゲーム開発チーム・クライアント開発
1フレームの計算に普段の数倍の時間がかかり、画面が一瞬止まります。
なぜ スキルエフェクトの急増、大量スポーン、UI全体の更新が1フレームに集中 → すると 16.7ms以内に終わらず、50〜300msかかる → 画面では 画面が一瞬止まり、次のフレームで全員が一気に動く
症状 カクつき , フリーズ
要因 ストール
誰に起きるか 自分だけ
いつ 人が集中したとき, 特定の操作をしたとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 重い処理を複数フレームに分散、プロファイラーで跳ねるフレームを特定、エフェクト数の上限設定。
数値の目安 60FPSの1フレームは16.7ms。50msを超えるフレームが1つあるだけでも「カクついた」と感じやすくなります。
グラフでは 不定期なスパイク · フレームタイム
確認箇所 PresentMonで、プレイ中のフレームタイム(FrameTime)と、そのフレームにCPU・GPUが費やした時間(CPUBusy・GPUBusy)を記録。モバイルはAndroid vitalsの低速セッション・低速レンダリングのメトリクス 該当する場合 普段は16.7ms前後のフレームタイムが50ms超に跳ねる瞬間が、スキル演出・大量スポーン・UI全体の更新と重なる。その瞬間もPingは変わらない 該当しない場合 フレームタイムは安定しているのに他のキャラクターだけが一瞬止まるなら、「補間バッファがないか短い」のようなネットワーク側。跳ねる間隔が規則的なら、まず「クライアントのガベージコレクション」を確認 確認手段 ユーザー側の環境で確認
出典3件
ID cg-gc · 主担当 ゲーム開発チーム・クライアント開発
使い終わったメモリ(ガベージ)を回収する間、ゲーム全体が止まります。一定の間隔でカクつくのが特徴です。
なぜ 毎フレーム、一時的な文字列・配列・リストを作っては捨てる → すると ガベージがたまると、GCがメインスレッドを止めて回収 → 画面では 数秒〜数十秒ごとに規則的にカクつく
症状 カクつき , フリーズ
要因 ストール
誰に起きるか 自分だけ
いつ 一定の周期で, 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 アロケーションの削減(文字列連結・LINQ・ラムダのキャプチャを避ける)、オブジェクトプール、インクリメンタルGCを有効のままにする(Unity 2020以降のデフォルト)、ロード画面のように止まっても問題ないタイミングで先にGCを実行。
数値の目安 通常は1回あたり数ms〜100ms、低スペックのスマホやメモリを多く使うゲームではそれ以上(実験では約150〜170ms)。UnityのGCは実行のたびにヒープ全体を調べるため、ゲームが使っているメモリが多いほど長くなります。
グラフでは 周期的なスパイク · フレームタイム、GCの実行時刻
確認箇所 開発ビルドで、UnityプロファイラーのGC.Collect・GC.Allocマーカーを確認。Unrealはstat GCとstat Hitches(t.HitchFrameTimeThresholdで指定した時間を超えるフレームをログに記録) 該当する場合 跳ねたフレームごとにGC.Collectの区間があり、その長さが跳ねた長さとほぼ同じで、間隔が数秒〜数十秒と規則的。人が多い場所ではフレームあたりのGC.Allocが増える 該当しない場合 跳ねたフレームにGCの区間がなければ「メインスレッドでの同期ロード・シェーダーコンパイル」か「大人数の描画負荷」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく UnityのようにC#を使うクライアントでよく起きます。戦闘ログの文字列、ダメージの数字、UIテキストを毎フレーム新しく作るコードが主な原因です。人が多い場所でだけカクつくなら、人数に比例してガベージが増えるコードがあるということです。インクリメンタルGCは1フレームに少しずつ(Unityのデフォルトは3ms)分けて回収しますが、回収する速度よりも速くガベージを生み出すと、結局一度にまとめて止まります。Unreal Engineにも使われなくなったゲームオブジェクトを片付ける独自のGCがあり、エンジンのバージョンや設定によって異なりますが、デフォルト設定では約1分ごとに実行され、1分間隔で一瞬止まる原因になることもあります。ゲームのルールをLuaのようなスクリプトで書いたクライアントでは、そのスクリプトのGCも別に動きます。
出典5件
ID cg-sync-load · 主担当 ゲーム開発チーム・クライアント開発
初めて見るエリア・モンスター・エフェクトを描画する直前に、ファイルの読み込みやシェーダーの生成を待って止まります。
なぜ 新しいエリアへの進入、初めて見るスキル・装備・モンスターの登場 → すると メインスレッドがファイルの読み込みとシェーダーコンパイルを待つ → 画面では 初回だけ0.1〜1秒止まり、2回目以降は問題ない
症状 フリーズ , カクつき
要因 ストール
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 非同期ロード、事前読み込み(プリウォーミング)、シェーダーをロード画面や初回起動時に事前コンパイル、ロード画面の活用。
数値の目安 シェーダー1つのコンパイルに数十ms、長ければ100ms以上。テクスチャの読み込みはストレージの速度によって数十〜数百ms。
グラフでは 接続直後・メンテ明けに急増 · フレームスパイクの回数(アップデート・ドライバー更新の直後)
確認箇所 PresentMonで同じルートを2回記録し、初回と2回目を比較。開発ビルドでは、Unrealでr.PSOPrecache.Validationを有効にしてstat PSOPrecacheとログの「PSO PRECACHING MISS」を、UnityではプロファイラーのTimelineで跳ねたフレームのロード・シェーダーの区間を確認 該当する場合 初めて行く場所・初めて使うスキルでだけ0.1〜1秒跳ね、2回目には消える。アップデートやグラフィックドライバー更新の直後に報告が集中し、その後減る 該当しない場合 同じ場所で毎回跳ねるなら、シェーダーキャッシュの問題とは別。ストレージが遅いPCでだけ移動のたびに繰り返すなら「ストレージが遅くアセットストリーミングが間に合わない」、専用GPUメモリがいっぱいなら「ビデオメモリ(VRAM)不足」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく PCでは、一度作ったシェーダーをグラフィックドライバーがシェーダーキャッシュに保存しておき、再利用します。そのため、グラフィックドライバーの更新やゲームのアップデートの直後はこのキャッシュが無効になり、問題なかった人もしばらくまたカクつきます。「アップデート後、初めて行く場所で毎回一瞬止まる」という報告が典型です。
出典5件
ID cg-asset-stream · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
HDDのような遅いストレージでは、オープンワールドのテクスチャ・モデルを読み込む速度が移動に追いつかず、オブジェクトの表示が遅れたり、ゲームが読み込みを待ってカクついたりします。
なぜ 乗り物・テレポートで高速に移動したり、人が多い場所に入ったりして、新しいテクスチャ・モデルが一気に必要になる → すると HDDのような遅いストレージが必要な速度で読み込めず読み込み要求がたまり、一部のロードはメインスレッドが完了まで待つ → 画面では テクスチャがしばらくぼやけ、建物・キャラクターの表示が遅れ、読み込みを待つ瞬間にカクつき・フリーズ
症状 表示されない・ゴースト , カクつき , フリーズ
要因 ストール
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時, 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
ゲーム開発チームの対応 読み込みをメインスレッドで待たない非同期ストリーミング、移動方向・速度に基づく先読み、低解像度(ミップマップ)・簡易モデルを先に表示して後で差し替え、高速移動中にストリーミングが遅れたら一時的に移動速度を制限するかロード画面を使用、最低・推奨スペックにSSDの要否を明記。
外部の対応 ユーザーにゲームをSSDにインストールするよう案内、同じディスクでダウンロードやウイルス対策ソフトのスキャンが動いていないか確認するよう案内。
数値の目安 Microsoftの説明によると、以前のハードディスクは1秒に数十MB、NVMe SSDは1秒に数GBを読み込み、前世代のゲームはストリーミングに1秒あたり50MB前後を使っていました。SSDの速度を前提にこれよりはるかに多く読み込むゲームをHDDで動かすと、読み込みが移動に追いつかなくなりがちです。
グラフでは 一部だけ高い · フレームスパイクの回数(ストレージの種類別)、ディスク読み込みの遅延
確認箇所 Windowsのパフォーマンスモニターで、PhysicalDisk\Avg. Disk sec/Read(読み込み1回の平均時間)・Current Disk Queue LengthとPresentMonのフレームタイムを、高速で移動しながらあわせて記録。開発ビルドではUnrealのstat Streaming・stat AsyncLoad、UnityプロファイラーのAssetBundle.asset/allAssets警告(ロード完了前に結果を要求し、メインスレッドが待つ)を確認 該当する場合 高速で移動するとディスク読み込みの遅延とキューが急上昇し、同じ時刻にフレームが跳ねたり、テクスチャ・オブジェクトの表示が遅れたりする。同じ場面をSSDで動かすと消える 該当しない場合 ディスクの負荷は低いのにテクスチャがぼやけるなら「ビデオメモリ(VRAM)不足」、同じ場所への2回目の訪問から問題なければ「メインスレッドでの同期ロード・シェーダーコンパイル」 確認手段 ユーザー側の環境で確認
もっと詳しく 初回だけ止まって次から問題ないなら「メインスレッドでの同期ロード・シェーダーコンパイル」に近く、ストレージが遅いPCでだけ移動のたびに繰り返すならこの原因です。ビデオメモリが足りずテクスチャを退避させては読み戻す「ビデオメモリ(VRAM)不足」もテクスチャのぼやけを起こすため、ディスクの読み込み待ちとビデオメモリの使用量をあわせて確認します。ウイルス対策ソフトのリアルタイムスキャンがゲームファイルを開くたびに割り込み、読み込みがさらに遅くなることもあります。
出典8件
大人数の描画負荷 Render/animation cost of crowds
ID cg-crowd · 主担当 ゲーム開発チーム・クライアント開発
攻城戦やワールドボスのように数百人が1つの画面に入ると、描画のコストそのものが処理しきれなくなります。
なぜ 1つの画面に数百人とエフェクトが重なる → すると アニメーション・影・名前表示・エフェクトのコストが人数に比例して増加 → 画面では FPSが60 → 15に落ち、すべての動きがカクつき、入力も遅れる
症状 カクつき , 入力遅延
要因 ストール
誰に起きるか 特定の場所・チャンネル, 自分だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 距離に応じた簡略化(LOD)、表示人数の上限、エフェクト簡略化オプション、アニメーション更新頻度の引き下げ。
数値の目安 キャラクター1人あたり0.02〜0.1msでも、300人なら6〜30ms。60FPSのフレームバジェットは16.7msなので、これだけで予算の1/3以上を使い、多い場合は超えます。
グラフでは 人数・負荷に連動して上昇 · フレームタイム、画面内のキャラクター数
確認箇所 PresentMonのフレームタイムとCPUBusy・GPUBusyを、攻城戦・ワールドボスの前後で比較。開発ビルドではUnrealのstat Unit(ゲームスレッド・レンダリングスレッド・GPUの時間) 該当する場合 画面内の人数が増えるほどフレームタイムも上がり、表示人数の制限やエフェクト簡略化オプションを有効にするとすぐに改善する 該当しない場合 人数と関係なく跳ねるなら「フレームタイムのスパイク」か「クライアントのガベージコレクション」。FPSは問題ないのに他の人の動きだけ遅れるなら「メインスレッドのパケット処理ボトルネック」 確認手段 ユーザー側の環境で確認
出典4件
ID cg-net-mainthread · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
受信したパケットをフレームごとに決まった量しか処理しないと、押し寄せたパケットがどんどん次のフレームへ持ち越されます。
なぜ 人が多い場所で、毎秒数千件の更新が届く → すると メインスレッドがフレームあたりの処理量の上限に達し、読み切れない → 画面では 他の人の動きがだんだん遅れ、まとめて反映される
症状 早送り , 入力遅延
要因 ストール, 遅延
誰に起きるか 特定の場所・チャンネル, 自分だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:受信・解析は別スレッドで行い、同じ対象の古い位置更新はまとめて最新のものだけを適用。サーバー:人が多い場所では遠くのキャラクターの更新を送る頻度を下げて送信量を削減。
数値の目安 処理しきれないパケットがたまると、数秒で1秒分の遅れになります。
グラフでは 人数・負荷に連動して上昇 · 未処理の受信パケット数、受信〜適用の遅延
確認箇所 クライアントがフレームごとに処理しきれず残したパケット数と、パケットの到着からゲームに適用するまでの遅延をログに記録し、周囲の人数とあわせて確認 該当する場合 人が多い場所で、残ったパケット数と適用までの遅延が増え続け、同じ時刻のPingとサーバーの送信間隔は正常 該当しない場合 適用までの遅延はないのにパケット自体の到着が遅いならネットワーク区間。フレームタイムが大きく上がるなら「大人数の描画負荷」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
補間バッファがないか短い Missing/short interpolation buffer
ID cg-no-buffer · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
サーバーのパケットを受け取ってすぐ描画すると、ジッター(到着間隔のばらつき)がそのまま画面に表れます。
なぜ 受信した位置をすぐに描画するか、バッファがジッターより短い → すると 遅れて届いたパケットの分だけ止まり、まとめて届いたパケットの分だけ跳ぶ → 画面では 他のキャラクターの動きがカクつく
症状 カクつき
要因 ジッター
誰に起きるか 自分だけ
いつ 常に
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:補間バッファを設け、回線の状態に応じてバッファの長さを自動調整。サーバー:バッファの分だけ過去の姿を見て撃っても判定が合うよう、ラグコンペンセーション(巻き戻し判定)を適用。
数値の目安 通常、サーバーがパケットを送る間隔の2倍程度(1秒に20回受信するなら100ms)をバッファとして持ちます。
グラフでは 最初から常に高い · パケットの到着間隔、補間バッファが空になった回数
確認箇所 クライアントで、サーバーパケットの到着間隔の分布と、補間する次のスナップショットがなくて止まったり外挿に切り替わったりしたフレーム数を記録 該当する場合 到着間隔のばらつきが補間バッファの長さを超えることが多く、そのたびにバッファが空になって他のキャラクターが一瞬止まる。バッファを長くすると減る 該当しない場合 バッファが十分なのに一瞬止まるなら、サーバーの送信間隔そのものが不規則でないか(ティックの遅延)を確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく バッファを長くすると滑らかになりますが、その分だけ相手の過去の姿を見ることになります。そのため攻撃の当たり判定では、サーバーが「その人が見ていた過去」まで巻き戻して確認するラグコンペンセーションを併用します。
出典3件
クライアントサイド予測の不一致 Prediction mismatch / reconciliation
ID cg-predict · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
自分のクライアントが先に動かして見せたのに、サーバーの計算結果が違うと、自分のキャラクターが引き戻されます。
なぜ クライアントがサーバーの確認前に先に動く(予測) → すると サーバーが衝突・移動速度・バフを違う形で計算するか、コマンドを受け取れない → 画面では 確認が届いたとき、自分のキャラクターが後ろへ引き戻される
症状 引き戻し
要因 パケットロス, 遅延
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:サーバーと同じ移動コードを使用、入力の重複送信、補正は滑らかに。サーバー:クライアントと同じ移動コードを使用、重複して届いた入力は入力番号で除外して1回だけ処理。
数値の目安 引き戻される距離は「ずれた時間 × 移動速度」。コマンドがいくつか消えるだけで1〜3m。
グラフでは 不定期なスパイク · サーバー補正(予測ミス)の回数
確認箇所 サーバーが送った位置補正の回数と補正距離を記録。UnrealではサーバーのClientAdjustPositionによる補正、UnityのNetcode for Entitiesでは予測ミスで巻き戻して再計算した回数を数える 該当する場合 引き戻しの報告時刻に補正が集中し、特定のバフ・地形・移動スキルで補正距離が繰り返し大きくなる 該当しない場合 補正がパケットロスの多いときにだけ集中するなら、入力パケットのロス(回線)側。補正がないのに他のキャラクターだけ引き戻されて見えるなら「過度な外挿(デッドレコニング)」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
固定タイムステップの追いつき処理の暴走 Fixed-timestep catch-up / spiral of death
ID cg-fixed-step · 主担当 ゲーム開発チーム・クライアント開発
一度止まった後、遅れた計算をまとめて処理しようとして、その計算のせいでさらに遅れます。
なぜ ゲームのシミュレーションを固定間隔で回している最中に、一度止まる → すると 遅れたステップを1フレームでまとめて計算 → 画面では 長いフレームが次々と続いて跳ねるか、上限に達して世界全体がスローモーションになる
症状 カクつき , 早送り , スローモーション
要因 ストール
誰に起きるか 自分だけ
いつ ときどきランダムに, 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 フレームあたりの追いつき処理の上限、余った時間は補間で処理。
グラフでは 不定期なスパイク · フレームタイム、フレームあたりの固定ステップ数
確認箇所 開発ビルドのプロファイラーで、1フレームに固定ステップが何回実行されたか(UnityではFixedBehaviourUpdateなどFixedUpdate段階のマーカー数)とフレームタイムをあわせて確認 該当する場合 長いフレーム1つの後に、ステップを何回も回す長いフレームが次々と続く。上限(UnityのMaximum Allowed Timestep)に達すると、ゲーム内の時間が実際より遅く流れる 該当しない場合 長いフレームが1回で終わるなら「フレームタイムのスパイク」か「クライアントのガベージコレクション」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく Unityの物理演算(FixedUpdate)が代表的な固定ステップです(デフォルト0.02秒、1秒に50回)。Time設定のMaximum Allowed Timestep(1フレームで追いつく最大時間、デフォルト約0.33秒)が追いつき処理の上限です。1フレームがこれより長いと、あふれた時間は捨てられ、その分ゲームの時計が実際より遅れます。
出典3件
時刻同期の誤差 Clock sync error
ID cg-clock · 主担当 ゲーム開発チーム・クライアント開発
クライアントが推定したサーバー時刻がずれていると、補間のタイミングやクールタイムの判定がずれます。
なぜ 接続時に一度だけサーバー時刻を合わせ、Pingが変わってもそのまま → すると 補間するタイミング・クールタイムが終わる時刻がサーバーとずれる → 画面では 相手がときどき一瞬止まる。クールタイムが終わったのにスキルが拒否される
症状 カクつき , 不発・ロールバック
要因 遅延
誰に起きるか 自分だけ
いつ 長時間稼働するほど, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 定期的な時刻同期(往復時間を測って補正)、急に変えず徐々に合わせる、経過時間はPCの時刻の代わりにモノトニッククロック(monotonic clock)で計測。
グラフでは 徐々に上昇 · 推定サーバー時刻の誤差
確認箇所 クライアントが推定したサーバー時刻と、サーバーがパケットに入れて送ったサーバー時刻(ティック番号)の差を定期的に記録 該当する場合 誤差が接続後の時間経過とともに大きくなるか、PCの時計が合わせられた瞬間に一気に跳ね、その頃にスキルの拒否や一瞬止まるという報告が増える 該当しない場合 誤差が小さいままなのにスキルが拒否されるなら、サーバーの判定・遅延側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく 経過時間をPCの日付・時刻(wall clock)で測ると、Windowsがインターネット時刻に合わせて時計を修正したり、ユーザーが時計を変更したりした瞬間に、ゲームの時刻が跳ねます。経過時間は巻き戻らないモノトニッククロック(monotonic clock、Stopwatchなど)で測る必要があります。
出典3件
float型で持つ時刻の精度低下 Float time precision loss on long sessions
ID cg-float-time · 主担当 ゲーム開発チーム・クライアント開発
ゲーム内の時刻を精度の低い小数形式(float)で持っていると、起動したままの時間が長いほど時間分解能(区別できる最小の時間差)が下がり、動きやエフェクトが震えます。
なぜ ゲーム起動後の経過時間をfloatに積算するか、そのままシェーダーに渡す → すると 起動したままの時間が長いほど、floatで表せる最小の差が大きくなる → 画面では 何日も起動したままのクライアントでだけ、キャラクター・アニメーション・流れるエフェクトが小刻みに震え、再起動すると直る
症状 カクつき
要因 ジッター
誰に起きるか 自分だけ
いつ 長時間稼働するほど
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 経過時間はdouble(64ビット)か整数で保持、シェーダーに渡す時間は一定周期でリセット、数日間にわたる長時間の自動テスト。
数値の目安 32ビットのfloatは有効数字が7桁ほどしかないため、起動から1日(約86,400秒)で時間分解能が約8msとなり60FPSの1フレーム(16.7ms)の半分ほど、1週間で約60msとなり1フレームより大きくなります。
グラフでは 徐々に上昇 · 連続起動時間別の震えの報告
確認箇所 震えの報告と一緒にクライアントの連続起動時間を受け取り、再起動の前後を比較。開発側では、ゲーム開始時刻の値を数日経過した値にして動かすテスト 該当する場合 何日も起動したままのクライアントでだけ震え、再起動すると消える。起動したままの時間が長いほどひどくなる 該当しない場合 起動直後から震えるなら「補間バッファがないか短い」か「タイマー分解能」 確認手段 ユーザー側の環境で確認
もっと詳しく オート狩りをオンにしたまま何日も終了しないモバイルMMOで特によく起きます。UnityのTime.timeもfloatなので、Unityはdouble型のTime.timeAsDoubleを別に用意し、こちらを推奨しています。
出典2件
ID cg-vsync · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
GPUが描画したフレームを何枚かキューにためておき、モニターの周期に合わせて出力する間、入力が遅れます。
なぜ グラフィックドライバーがフレームを1〜3枚先にキューにためる → すると 入力が画面に反映されるまで、その分余計に時間がかかる → 画面では Pingは低いのに、操作が重くもたつく
症状 入力遅延 , カクつき
要因 遅延
誰に起きるか 自分だけ
いつ 常に
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
ゲーム開発チームの対応 低遅延モードへの対応、フレームキューを減らす、リフレッシュレートより少し低く設定するフレームレート上限オプションの提供、スマホではフレームペーシング機能を有効化。
外部の対応 ユーザーに、可変リフレッシュレート対応モニターと組み合わせてリフレッシュレートより少し低いフレームレート上限を設定すること、グラフィックドライバーの低遅延モードを有効にすることを案内。
数値の目安 60Hzでは1枚あたり16.7ms。CPUがGPUや画面の周期より速く、キューの3枚(DirectX 11のデフォルト)が埋まると、50msが上乗せされます。ダブルバッファのV-Syncでは、17msかかったフレームが次の画面更新タイミング(33.3ms)まで待ち、その間は前のフレームがもう一度表示されます。
グラフでは 最初から常に高い · 入力〜画面の遅延
確認箇所 PresentMonのMsClickToPhotonLatency・MsAllInputToPhotonLatency(マウス・キーボードの入力から画面への出力まで)とDisplayLatencyを、V-Sync・低遅延モード・フレームレート上限を切り替えながら比較。MsPCLatency(PCが入力を受けてから画面に送るまで)は、ゲームがPC Latencyイベントを出力する場合にだけ記録される 該当する場合 V-Syncを有効にしたときやフレームレート上限がないときにこの遅延が1〜2フレーム(数十ms)増え、低遅延モードやリフレッシュレートより少し低いフレームレート上限では減る。Pingは変わらない 該当しない場合 PC内の遅延は低いのに操作が遅れるなら「ディスプレイ・入力デバイス・フレーム生成による遅延」、Pingが高いならネットワーク側 確認手段 ユーザー側の環境で確認
もっと詳しく V-Sync(垂直同期)は、モニターが画面を切り替える瞬間にだけ新しいフレームを出力する設定です。ティアリングはなくなりますが、その瞬間を待つ分だけ入力が遅れ、FPSが60を下回ると60と30の間を行き来してカクつきます。可変リフレッシュレート(VRR)対応モニターは、フレームの準備ができたタイミングに合わせて画面を切り替えるため、この待ち時間を減らせます。スマホでも同じことが起きます。30FPSのゲームが60Hzの画面にフレームを均等に出力できないと、平均は30FPSなのに1枚あたりの表示時間が49・16・33msのようにばらつき、カクつきます(Androidの開発者向けドキュメントの例)。Androidのフレームペーシング(フレームの出力間隔をそろえる)ライブラリや、エンジンの同様のオプションで軽減します。
出典5件
ID cg-leak · 主担当 ゲーム開発チーム・クライアント開発
長く起動しておくほどメモリが増えてだんだん重くなり、最後にはゲームが強制終了します。
なぜ エリアを行き来するたびに、テクスチャ・UI・エフェクトが解放されずに残る → すると GCが頻繁になり、OSのメモリが足りなくなってスワップが発生 → 画面では 数時間プレイした後、だんだんカクつくようになり、強制終了(プレイヤーには切断のように見える)
症状 カクつき , 切断
要因 ストール
誰に起きるか 自分だけ
いつ 長時間稼働するほど
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 エリア切り替え時にメモリ使用量を計測、解放されないテクスチャ・UI・エフェクトを見つけて修正、長時間の自動テスト(ソークテスト)。
グラフでは 徐々に上昇 · ゲームプロセスのメモリ
確認箇所 パフォーマンスモニターでProcess(ゲーム)\Private Bytesを数時間記録。モバイルはAndroidのApplicationExitInfoの終了理由(REASON_LOW_MEMORY)とiOSのjetsamレポート 該当する場合 エリアを行き来するたびにメモリが上がって下がらず、起動したままの時間が長いほどカクつき・強制終了が増える 該当しない場合 メモリは一定なのに、長く起動しておくほど震えるだけなら「float型で持つ時刻の精度低下」 確認手段 ユーザー側の環境で確認
もっと詳しく スマホは主にメモリを圧縮してしのぎます。それでもメモリが足りなくなると、OSがゲームをすぐに終了させます(落ちる)。RAMが少ない端末ほど先に終了させられます。
出典4件
ID cg-crash · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
処理されないエラーでゲームが終了します。プレイヤーには切断のように見えますが、サーバーは正常です。
なぜ null参照、メモリ不足、グラフィックドライバーのエラー → すると ゲームプロセスが強制終了 → 画面では 「落ちた」という報告。同じ時刻、ほかの人は問題ない
症状 切断
要因 ストール
誰に起きるか 自分だけ
いつ 特定の操作をしたとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
ゲーム開発チームの対応 クラッシュレポートの収集、端末・ドライバー別の統計、件数の多いエラーから修正。
外部の対応 特定のグラフィックドライバーのバージョンに集中していれば、ユーザーにドライバーの更新を案内。
グラフでは 一部だけ高い · クラッシュ数(端末・グラフィックドライバー・ビルド別)
確認箇所 クラッシュレポートとAndroid vitalsのクラッシュ率を、端末・ドライバー・ビルド別に確認。ユーザーのPCでは、イベントビューアーのアプリケーションログにあるイベントID 1000(障害が発生しているモジュールの名前)と「Display driver stopped responding and has recovered」の記録 該当する場合 切断の報告時刻にクラッシュの記録があり、同じ時刻に同じサーバーのほかのユーザーは正常。特定の端末・ドライバーのバージョン・モジュールに集中 該当しない場合 クラッシュの記録がなく接続だけ切れたなら「NATマッピングの期限切れ」か回線側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID cg-anticheat · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
チートを防ぐためにゲームと一緒に動くセキュリティモジュールが、定期的に検査を行います。検査が重かったり、セキュリティサーバーとやり取りするハートビート(定期的な生存確認の信号)が遅れたりすると、カクついたり切断されたりします。
なぜ セキュリティモジュールが定期的に、ゲームのメモリ・実行中のプログラム・ドライバーを検査 → すると 検査の間ゲームスレッドが止まるか、ハートビートが時間どおりに届かない → 画面では 一定の間隔で一瞬止まり、ひどいとセキュリティエラーの案内とともに切断
症状 カクつき , フリーズ , 切断
要因 ストール
誰に起きるか 自分だけ
いつ 一定の周期で, 接続直後・メンテ明け, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:重い検査はゲームスレッドの外で少しずつ分けて実行、セキュリティモジュールのバージョン別にカクつきや落ちた件数の統計を比較(アップデート直後に集中していればセキュリティモジュールのベンダーに連絡)。サーバー:ハートビートが1〜2回遅れる程度は許容。
数値の目安 軽い検査は通常1msもかかりませんが、ゲームスレッドで動く重い検査は、実装によっては1回で数十〜数百msを占めることもあります。
グラフでは 周期的なスパイク · フレームタイム、アンチチートによるキック数
確認箇所 PresentMonのフレームタイムで跳ねる間隔を測り、サーバーが受け取ったアンチチートのキック理由(EOSではClientActionReasonのAuthenticationFailed / Authentication Timed Outなど)を、セキュリティモジュールのバージョン・スペック別に集計 該当する場合 ゲームの状況と関係なく一定間隔の短い停止が繰り返され、セキュリティモジュールのアップデート直後に、特定のスペックでカクつき・認証タイムアウトによるキックが増える 該当しない場合 セキュリティモジュールのバージョンと関係なく、すべてのスペックで同じ間隔なら「クライアントのガベージコレクション」か「バックグラウンドプロセスによるCPU占有」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく セキュリティモジュールはドライバーとしてOSの深い部分に入り込んでいるため、ウイルス対策ソフト・オーバーレイ・ほかのゲームのセキュリティモジュールと衝突することもあります。セキュリティモジュールのアップデート直後に、特定のスペックでだけカクつく・落ちるという報告が集中したら、まずこれを疑います。
出典2件
L2 クライアントのOS・端末
原因15件 · メインページの章
ID co-background · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ウイルス対策ソフトのスキャン、Windows Update、配信ソフト、ブラウザの動画がコアを占有すると、ゲームスレッドがCPUを割り当ててもらえずに待たされます。
なぜ 他のプログラムがCPUコアを長時間占有 → すると ゲームスレッドがスケジューリング待ちになる → 画面では フレームが遅れ、受信したパケットの処理も遅れる
症状 カクつき , 早送り
要因 ストール
誰に起きるか 自分だけ
いつ ときどきランダムに, 一定の周期で
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 ゲームスレッドの優先度の調整、カクつきが起きたときのログにPC全体のCPU使用率も記録して、他のプログラムが原因かどうかを区別。
外部の対応 ユーザーに、Windowsのゲームモードを有効にすること、プレイ中は不要なプログラム(ウイルス対策ソフトのスキャン・Windows Update・配信ソフト・ブラウザの動画)を終了することを案内。
数値の目安 Windowsは通常、1回に数ms〜数十msずつコアを割り当てます。スケジューリングで一度後回しにされるだけで、1フレームが消えます。
グラフでは 不定期なスパイク · PC全体のCPU使用率、フレームタイム
確認箇所 タスクマネージャーのプロセスタブのCPU列と、パフォーマンスモニターのProcessor Information(_Total)\% Processor Timeを、PresentMonのフレームタイムとあわせて記録。ウイルス対策ソフトが疑わしければ、New-MpPerformanceRecordingで記録し、Get-MpPerformanceReportでスキャン時間の長いファイル・プロセスを確認 該当する場合 カクついた時刻に他のプログラム(ウイルス対策ソフトのスキャン・アップデート・配信ソフト)のCPU使用率が急上昇するか、ゲームフォルダーのファイルがスキャン時間の上位に入る。そのプログラムを終了するか除外に設定すると消える 該当しない場合 CPU使用率が低いのに画面全体が一瞬止まり、音にノイズが入るなら「NICの省電力・ドライバーの問題」(DPC遅延) 確認手段 ユーザー側の環境で確認
もっと詳しく Windowsは前面に表示しているウィンドウ(フォアグラウンド)のプログラムに少し高い優先度を与えますが、コアの数より実行すべき処理が多ければ、ゲームも待たされます。ウイルス対策ソフトは、CPUを使うことよりも「リアルタイム監視」で割り込むことのほうが多いです。ゲームがファイルを開くたびにスキャンするため、アセットを読み込む瞬間の停止が長くなります。
出典6件
ID co-power · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ノートPCのバッテリーモード、スマホの省電力モード、端末の発熱によって、CPU・GPUの速度が落ちます。発熱の場合は、最初は問題なく、しばらくしてから重くなるのが特徴です。
なぜ バッテリー・省電力モードか、端末が熱くなっている → すると CPU・GPUのクロックを、端末によって30〜50%下げる → 画面では 省電力モードは起動直後から、発熱は数分〜20分ほどプレイした後から、FPSが下がってカクつく
症状 カクつき , 入力遅延
要因 ストール
誰に起きるか 自分だけ
いつ 長時間稼働するほど, 常に
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 グラフィックオプションの自動調整、フレームレート上限による発熱管理、OSが通知する発熱段階(iOSのthermalState、Androidの発熱状態API)を見て先にオプションを下げる、GPUを2つ搭載したノートPCでディスクリートGPUを使うよう実行ファイルで指定(NvOptimusEnablement・AmdPowerXpressRequestHighPerformanceのエクスポート)。
外部の対応 ユーザーに、省電力モードを解除すること、ノートPCは電源につなぐことを案内。「いいノートPCなのにFPSが低い」という報告なら、ゲームがどちらのGPUで動いているかを確認し、Windowsのグラフィックの設定でゲームを高パフォーマンスのGPUに指定するよう案内。
グラフでは 徐々に上昇 · FPS、CPU・GPUのクロック
確認箇所 PresentMonのCPUFrequency・GPUFrequency・CPUTemperature・GPUTemperatureをフレームタイムとあわせて20〜30分記録し、タスクマネージャーのプロセスタブのGPUエンジン列で、ゲームがどちらのGPUで動いているかを確認。モバイルは、Androidの発熱API(getThermalHeadroom、発熱状態)とiOSのthermalStateをFPSとあわせて記録 該当する場合 温度が上がってクロックが下がった時点からFPSが落ちるか、バッテリー・省電力モードのときだけクロックが低い。または、ゲームが内蔵GPUで動いている 該当しない場合 クロック・温度が変わらないのにFPSが落ちるなら「バックグラウンドプロセスによるCPU占有」か「クライアントのメモリリーク」 確認手段 ユーザー側の環境で確認
もっと詳しく GPUを2つ搭載したノートPCは、電力を節約するためにゲームを遅い内蔵GPUで動かすことがあります。「いいノートPCなのにFPSが低い」という報告なら、まずゲームがどちらのGPUで動いているかを確認します。
出典5件
タイマー分解能 Timer resolution (Windows 15.6ms)
ID co-timer · 主担当 ゲーム開発チーム・クライアント開発
Windowsのデフォルトのタイマーは15.6ms単位なので、「1msだけ待つ」が実際には次のタイマー周期まで、長いと15.6msまで延びます。
なぜ フレームレート制限・パケット送信をSleep(短い待機)で実装 → すると OSが15.6ms単位でしか起こしてくれない → 画面では フレーム間隔と入力の送信間隔がばらつく
症状 カクつき
要因 ジッター
誰に起きるか 自分だけ
いつ 常に
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 高分解能タイマーの使用、Sleepで待つ代わりにイベント・V-Syncを基準にしたペーシング。
数値の目安 15.6ms単位では16.7msの間隔に合わせられず、フレーム間隔が15.6msと31.2msの間を行き来します。
グラフでは 最初から常に高い · フレーム間隔の分布
確認箇所 PresentMonのMsBetweenPresents(フレーム間隔)の分布と、powercfg /energyレポートの「Platform Timer Resolution」項目(タイマー分解能を変更したプロセス)を確認 該当する場合 フレーム間隔が15.6msと31.2msのように15.6msの倍数に集中し、ゲームがより高いタイマー分解能を要求していない 該当しない場合 間隔が均等に散らばっているなら、タイマーよりも「バックグラウンドプロセスによるCPU占有」やフレーム負荷側 確認手段 ユーザー側の環境で確認
もっと詳しく 以前のWindowsでは、1つのプログラムがタイマーを1msに変更すると、すべてのプログラムに適用されていました。そのため「ブラウザを開いておくとゲームが滑らかになる」という話もありました。Windows 10 バージョン2004からは要求したプログラムにだけ適用され、Windows 11では、最小化されたり完全に隠れていて音も出していないウィンドウの要求を適用しないことがあります。
出典6件
ID co-mobile-bg · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
通知を見ようとアプリをいったんバックグラウンドに移すと、OSが数秒後にアプリを一時停止(suspend)し、その間にサーバーは自分を切断します。
なぜ メッセージの確認・電話でゲームをバックグラウンドに移す → すると ゲームエンジンがゲームの進行を止め、OSもすぐにアプリとネットワークを停止させる → 画面では 戻るとすでに切断されていて、再接続
症状 切断
要因 ストール, パケットロス
誰に起きるか 自分だけ
いつ しばらく放置した後, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:戻ったら切れた接続を待たずに、セッショントークンですぐに自動再接続(再ログインなしで接続を引き継ぐ)、最新の状態を一度に受け取って合わせる。サーバー:ハートビートが途切れたら接続は片付けるが、キャラクターのセッションは短い猶予時間のあいだ維持(すぐに追い出さない)、その間に再接続すればセッショントークンで引き継ぐ。
数値の目安 ゲームエンジンは通常、バックグラウンドに移した瞬間に止まります。iOSは数秒、追加の時間をもらってもたいてい数十秒以内にアプリを一時停止し、Android 14以降は画面から外れたアプリを10秒ほどで凍結(freeze)します。
グラフでは 接続が一斉に切れる · 切断数(ハートビートのタイムアウト)、アプリの一時停止の記録
確認箇所 クライアントログにあるアプリの一時停止・復帰の時刻(UnityではOnApplicationPause)と、サーバーの切断理由・時刻を、セッションIDで突き合わせる。Androidは、ApplicationExitInfoに残ったプロセスの終了理由(REASON_LOW_MEMORYなど)もあわせて確認 該当する場合 サーバーのハートビートタイムアウトによる切断の直前にクライアントが一時停止に入り、復帰直後に再接続している 該当しない場合 アプリをフォアグラウンドにしている間に切れたなら「NATマッピングの期限切れ」「通信事業者の共有IP(CGNAT)」「Wi-Fi ↔ LTE・5Gの切り替え」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく スマホはメモリが足りないと、バックグラウンドのゲームを完全に終了させることもあります。カメラや決済・認証アプリから戻るとゲームが最初から起動し直すのはこのためです。低スペックの端末ほどよく起きます。
出典5件
ID co-netswitch · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・ネットワークインフラ
家の外に出てWi-Fiが切れ、LTE・5Gに切り替わると、自分のIPアドレスが変わり、それまでの接続が無効になります。
なぜ Wi-Fiの電波が弱くなり、モバイル回線に切り替わる → すると 自分のIPアドレスが変わり、古いアドレスで確立した接続ではもうやり取りできない → 画面では 少し止まった後に切断、または再接続
症状 フリーズ , 切断
要因 パケットロス
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 サーバー:アドレスが変わってもセッショントークンで同じプレイヤーとして引き継ぎ、古いアドレスの接続はすぐに片付ける。アドレスが変わっても接続が続くプロトコル(QUICのコネクションマイグレーションなど)を検討。クライアント:ネットワークの切り替えを検知したら、ハートビートのタイムアウトを待たずにセッショントークンですぐ再接続。
インフラチームの対応 QUICのコネクションマイグレーションを使う場合は、ロードバランサーがアドレス・ポートの代わりにコネクションIDでサーバーを選ぶよう設定(アドレス・ポートで選ぶと、アドレスが変わったパケットが別のサーバーへ行ってしまう)。
グラフでは 接続が一斉に切れる · 切断・再接続の数、再接続時に変わったIP
確認箇所 サーバーの接続ログで、同じセッショントークンが別のIPから再接続した記録を探し、クライアントのデフォルトネットワーク変更コールバック(registerDefaultNetworkCallback)の時刻と突き合わせる 該当する場合 切断直後に再接続したIPが、Wi-Fi(自宅回線)のアドレス帯からモバイルキャリアのアドレス帯へ、またはその逆へ変わっていて、その直前にネットワーク切り替えのコールバックが来ている 該当しない場合 IPが変わらないのに切れたなら「基地局のハンドオーバー(移動中)」か「モバイル電波の弱さ・不感地帯」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID co-security · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ウイルス対策ソフト・ファイアウォールがすべてのパケットを検査すると遅延が増え、行き過ぎるとゲームを攻撃と誤認してブロックします。
なぜ セキュリティソフトが送受信パケットを1つずつ検査 → すると パケットごとに遅延が加わり、検査が追いつかないと破棄される → 画面では Pingが不規則に跳ねるか、接続がブロックされる
症状 カクつき , 接続不可・無限ロード
要因 ジッター, パケットロス
誰に起きるか 自分だけ
いつ 常に, 接続直後・メンテ明け
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 セキュリティソフトの互換性リストの管理、インストール時にWindowsファイアウォールへゲームの例外を登録。
外部の対応 ユーザーに、セキュリティソフトでゲームを除外に登録するよう案内。ゲームを攻撃と誤認する場合は、セキュリティソフトのベンダーに誤検知の修正を依頼。
数値の目安 正常時のパケット検査にかかる時間は、通常1msにも満たない程度です。問題になるのは、検査モジュールの処理が追いつかないときやバグがあるとき、ゲームの通信を攻撃と誤認したときです。
グラフでは 一部だけ高い · RTT・接続失敗(ユーザー別)
確認箇所 セキュリティソフトを一時的に無効にするか、ゲームを除外に登録してから比較。Windowsでは、監査ポリシーのAudit Filtering Platform Connection・Audit Filtering Platform Packet Dropを有効にするとセキュリティログに5157(接続のブロック)・5152(パケットのブロック)が記録され、パフォーマンスモニターのWFPv4\Packets Discarded/secで破棄されたパケット数を確認できる 該当する場合 ゲームサーバーのアドレスへの接続・パケットのブロック記録が残るか、セキュリティソフトを無効にするとPingのスパイク・接続不可が消える 該当しない場合 セキュリティソフトと関係なく、同じ家のほかの端末でも同じならルーター・回線側 確認手段 ユーザー側の環境で確認
出典6件
受信バッファのあふれ Socket receive buffer overflow
ID co-rcvbuf · 主担当 ゲーム開発チーム・クライアント開発
ゲームの処理が忙しく、ソケット(OSが提供するネットワーク送受信のインターフェース)からパケットを取り出すのが遅れると、OSのバッファがあふれます。
なぜ フレームが遅れ、ゲームがソケットを読むのが遅くなる → すると OSの受信バッファがいっぱいになり、UDPは破棄され、TCPは受信ウィンドウを縮めて送信側を止めさせる → 画面では ワープ(UDP)または早送り(TCP)
症状 ワープ , 早送り
要因 パケットロス, ストール
誰に起きるか 自分だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 受信専用スレッド、バッファサイズの調整(SO_RCVBUF)。
数値の目安 デフォルトの受信バッファは、OS・設定によって数十〜数百KB。人が多い場所の更新は、1秒に数百KBになることもあります。
グラフでは 人数・負荷に連動して上昇 · UDP受信バッファでの破棄数、フレームタイム
確認箇所 Windowsのパフォーマンスモニターで、Microsoft Winsock BSP\Dropped Datagrams(ソケットの受信バッファ不足で破棄されたUDPの数)とUDPv4\Datagrams Received Errorsをフレームタイムとあわせて記録し、ゲーム側では受信パケットの連番の抜けを数える 該当する場合 人が多い場所や長いフレームの直後にDropped Datagramsが増え、同じ瞬間にゲームの連番に抜けが出る。同じ時刻に回線側のパケットロスはない 該当しない場合 Dropped Datagramsは変わらないのに連番だけ抜けるなら、経路上のパケットロス 確認手段 ユーザー側の環境で確認
出典5件
ID co-swap · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ブラウザのタブを数十個開いたままゲームを動かすと、OSがゲームのメモリの一部をディスクに追い出します。
なぜ 全体のRAMが足りなくなる → すると OSが今すぐには使わないゲームのメモリをディスクに移す → 画面では その部分を再び使う瞬間に、ストレージによって数十〜数百ms止まる
症状 フリーズ , カクつき
要因 ストール
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時, ときどきランダムに
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 メモリ使用量の削減、空きメモリが少なければ警告を表示。
外部の対応 ユーザーに最低スペックを案内、プレイ中は他のプログラム(ブラウザのタブなど)を閉じるよう案内。
グラフでは 不定期なスパイク · ハードページフォールト、メモリ使用量
確認箇所 パフォーマンスモニターのMemory\Pages Input/sec(ハードページフォールトを解決するためにディスクから読み込んだページ数)と、タスクマネージャーのパフォーマンスタブのメモリ使用量・コミット済みを、フレームタイムとあわせて記録 該当する場合 止まった瞬間にPages Input/secが急上昇し、メモリがほぼいっぱい。ブラウザなど他のプログラムを閉じると消える 該当しない場合 メモリに余裕があり、Pages Input/secが落ち着いているなら「メインスレッドでの同期ロード・シェーダーコンパイル」か「ストレージが遅くアセットストリーミングが間に合わない」 確認手段 ユーザー側の環境で確認
出典3件
ID co-vram · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
グラフィックオプションが必要とするメモリがグラフィックボードのメモリより大きいと、OSがテクスチャをPCのメモリへ追い出してはまた戻すため、カクつきます。
なぜ 高いテクスチャ設定や、人が多い場所のさまざまな装備・エフェクトで、グラフィックボードのメモリがいっぱいになる → すると OSが今すぐには使わないテクスチャをPCのメモリに移し、必要になると遅いPCIeバスで再び戻す → 画面では 新しい場面や新しいキャラクターが見えるたびに一瞬止まり、テクスチャがしばらくぼやける
症状 カクつき , フリーズ
要因 ストール
誰に起きるか 自分だけ
いつ 人が集中したとき, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
ゲーム開発チームの対応 グラフィックボードのメモリ容量に合わせたオプションのデフォルト値、メモリ予算を超えたらテクスチャ品質を自動で下げる、人が多い場所ではキャラクターのテクスチャを簡略化。
外部の対応 ユーザーにテクスチャ設定を下げるよう案内。クライアントを2つ起動する場合は、さらに設定を下げるよう案内。
数値の目安 グラフィックボードのメモリは1秒に数百GBを読み込めますが、PCのメモリとやり取りするPCIeバスは世代によって1秒に16〜64GB前後で、10倍以上遅くなります。
グラフでは 上限で頭打ち · 専用GPUメモリ、共有GPUメモリ
確認箇所 タスクマネージャーのパフォーマンスタブにあるGPU項目の、専用GPUメモリ・共有GPUメモリのグラフ(詳細タブにプロセスごとの列も追加可能)を、PresentMonのフレームタイムとあわせて確認 該当する場合 専用GPUメモリが上限に張り付いて頭打ちになり、共有GPUメモリが増えている間に一瞬止まることが多い。テクスチャ設定を下げると消える 該当しない場合 専用メモリに余裕があれば「ストレージが遅くアセットストリーミングが間に合わない」か「メインスレッドでの同期ロード・シェーダーコンパイル」 確認手段 ユーザー側の環境で確認
もっと詳しく Windowsのタスクマネージャーで、GPU項目の「専用GPUメモリ」がいっぱいになり「共有GPUメモリ」が増えていれば、この状態です。同じPCでクライアントを2つ起動すると、さらに早くいっぱいになります(「メモリ・VRAM不足によるストリーミングの失敗」の項目)。
出典4件
ID co-wifi-scan · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
OSが周囲のWi-Fiを探すために定期的にチャンネルを切り替えている間、通信が一瞬止まります。
なぜ OS・ドライバーが一定周期で周囲のWi-Fiを検索 → すると 検索している間、送受信が一瞬止まる → 画面では 正確に一定の間隔(例:60秒ごと)でPingが跳ねる
症状 カクつき , ワープ
要因 ジッター
誰に起きるか 自分だけ
いつ 一定の周期で
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 プレイ中は無線の検索を減らすモードを要求(AndroidはWi-Fi低遅延モードWIFI_MODE_FULL_LOW_LATENCY、WindowsはWlanSetInterfaceのメディアストリーミングモード。端末・ドライバーによっては効果がないこともある)。
外部の対応 ユーザーに、有線接続、位置情報サービス・Wi-Fiの自動検索の設定調整、無線LANドライバーの更新を案内。
数値の目安 通常は1回あたり数十〜数百ms。規則的すぎるなら、まずこの原因を疑います。
グラフでは 周期的なスパイク · ルーターまでのRTT
確認箇所 プレイ中にping /tでルーターのアドレス(ipconfigのデフォルトゲートウェイ)を数分間測り、跳ねる間隔を測定。有線に切り替えて同じ測定 該当する場合 ルーターまでのPingが正確に一定の間隔(例:60秒)で数十〜数百ms跳ね、有線では消える 該当しない場合 跳ねる間隔が不規則なら「Wi-Fiの干渉・電波の弱さ」。ルーターまでは問題なく、その先だけ跳ねるなら回線・通信事業者の区間 確認手段 ユーザー側の環境で確認
出典5件
ID co-driver · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
有線LANアダプター・Wi-Fiチップがパケットの合間に省電力状態に入ると、再び動き出すまでに時間がかかります。
なぜ ネットワークデバイスの省電力機能が有効か、ドライバーが古い → すると 省電力状態からの復帰(wake-up)の遅延、ときどきデバイスの再起動 → 画面では 不規則な遅延、まれに数秒止まる
症状 カクつき , フリーズ
要因 ジッター, パケットロス
誰に起きるか 自分だけ
いつ しばらく放置した後, ときどきランダムに
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 Androidクライアントは、プレイ中に低遅延Wi-Fiモード(WIFI_MODE_FULL_LOW_LATENCY)を要求してWi-Fiの省電力をオフにする。
外部の対応 ユーザーに、ネットワークドライバーの更新、デバイスマネージャーでネットワークデバイスの省電力を解除することを案内。画面全体が一瞬止まり音にノイズが入るなら、LatencyMonで原因のドライバーを見つけるよう案内。
グラフでは 不定期なスパイク · DPC・ISRの時間、ルーターまでのRTT
確認箇所 Windows Performance Recorder(WPR)で記録し、Windows Performance Analyzer(WPA)のDPC/ISRグラフで長く実行されているドライバー(Module列)を探す。デバイスマネージャーで、ネットワークアダプターの電源の管理(省電力)設定を確認 該当する場合 一瞬止まった時刻にネットワークドライバーのDPC・ISRが数msずつ続くか、省電力をオフにすると不規則な遅延が消える 該当しない場合 DPCが短く、省電力をオフにしても同じなら「Wi-Fiの干渉・電波の弱さ」か「Wi-Fiのバックグラウンドスキャン」 確認手段 ユーザー側の環境で確認
もっと詳しく ドライバーが割り込みの処理でCPUを長く占有すると(WindowsではDPC遅延と呼びます)、その間ゲームスレッドもコアを使えません。このときはCPU使用率が低いのに画面全体が一瞬止まり、音にもノイズが入ります。LatencyMonのようなツールでどのドライバーかを特定でき、Wi-Fi・有線LANのドライバーがよくある原因です。
出典4件
ID co-other-apps · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
クラウド同期、大容量のダウンロード、ゲームのアップデートが同じPCで動いていると、ゲームのパケットがキューで待たされます。
なぜ 他のアプリが上り・下りを目いっぱい使う → すると PCとルーターのキューにゲームのパケットがたまる → 画面では Pingの急上昇、入力遅延、早送り
症状 入力遅延 , 早送り
要因 遅延, ジッター
誰に起きるか 自分だけ, 同じ家
いつ ときどきランダムに
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 自社のランチャー・パッチャーは、プレイ中にバックグラウンドのダウンロードを止めるか速度を制限。
外部の対応 ユーザーに、ダウンロード速度の制限、プレイ中は自動更新をオフにすることを案内。
グラフでは 人数・負荷に連動して上昇 · RTT、PCの送受信量
確認箇所 パフォーマンスモニターのNetwork Interface\Bytes Sent/sec・Bytes Received/secとPingをあわせて記録。Pingを測りながらわざと大容量の転送をかける、バッファブロートテストと同じ方法 該当する場合 ダウンロード・アップロードが回線速度近くまで埋まっている間、Pingが数十〜数百ms上がり、転送を止めるとすぐ戻る 該当しない場合 PCの送受信量が少ないのにPingが上がるなら、同じ家のほかの端末による「バッファブロート(ルーターのキュー)」か、通信事業者の区間 確認手段 ユーザー側の環境で確認
出典4件
ID co-unfocused · 主担当 ゲーム開発チーム・クライアント開発
ほかのウィンドウを見たりゲームを最小化したりすると、ゲームとWindowsが電力を節約するためにゲームの処理を遅くします。戻ると遅れていたパケットが押し寄せるか、すでに切断されています。
なぜ Alt+Tabでほかのウィンドウを見るか、ゲームを最小化 → すると ゲームが見えない間はFPSを大きく下げるか止め、Windowsも見えないプログラムの優先度を下げる → 画面では 戻った瞬間に早送り、長くバックグラウンドにしていたら切断
症状 早送り , カクつき , 切断
要因 ストール
誰に起きるか 自分だけ
いつ 特定の操作をしたとき, しばらく放置した後
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 ウィンドウが見えなくてもパケットの受信とハートビートは別スレッドで継続、エンジンの「バックグラウンドで実行」設定を確認、復帰時に最新の状態へ一度に合わせる。
数値の目安 ウィンドウが見えないときにFPSを5〜10に下げると、1フレームが100〜200ms。パケットをフレームごとに処理するゲームは、その分パケットを読むのが遅れます。
グラフでは 途切れた後にまとめて到着 · フレーム間隔(ウィンドウ切り替えの前後)、処理したパケット数
確認箇所 PresentMonを動かしたままAlt+Tab・最小化を行い、ウィンドウが見えないときのフレーム間隔を確認。ゲームのログにウィンドウのフォーカスが変わった時刻を記録し、切断理由と突き合わせる 該当する場合 ウィンドウが見えない間にフレーム間隔が100ms以上に延びるか記録が途切れ、戻った瞬間に遅れていたパケットを一気に処理して早送りになる。長くバックグラウンドにしておくと、ハートビートのタイムアウトで切断 該当しない場合 ウィンドウを表示したままでも同じなら「バックグラウンドプロセスによるCPU占有」かネットワーク側 確認手段 ユーザー側の環境で確認
もっと詳しく Windows 11は、最小化されたり完全に隠れていて音も出していないウィンドウのプログラムに、1msタイマーを保証しません。バッテリーで動いているノートPCでは、そうしたプログラムを最も電力消費の少ない速度に落とし、種類の異なるコアが混在するCPUなら、遅い高効率コアで動かすこともあります。同じPCの2つのクライアントのうちバックグラウンド側だけがおかしいなら、「バックグラウンドウィンドウの処理制限」の項目もあわせて確認してください。
出典4件
オーバーレイソフトの干渉 Overlays and screen hooks
ID co-overlay · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
メッセンジャー・ランチャー・録画・FPS表示のソフトが、ゲーム画面の上に自分のUIを重ねて描くため、ゲームのレンダリング処理に割り込みます(フック)。フレームごとの処理が増え、ときどきゲームとぶつかって一瞬止まったり、ゲームが強制終了したりします。
なぜ メッセンジャー・ゲームランチャー・グラフィックボードのツール・録画ソフトのオーバーレイが有効 → すると フレームを画面に出力するたびにオーバーレイが割り込み、自分のUIを重ねて描く → 画面では フレームが少しずつ遅れ、通知が出た瞬間に一瞬止まったり、グラフィックの不具合・強制終了が起きたりする(プレイヤーには切断のように見える)
症状 カクつき , フリーズ , 切断
要因 ストール
誰に起きるか 自分だけ
いつ 常に, ときどきランダムに
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 クラッシュレポートとカクつきのログに、実行中のオーバーレイの一覧もあわせて収集。
外部の対応 報告があれば、ユーザーにオーバーレイをすべてオフにして再度試すよう案内。
グラフでは 一部だけ高い · フレームタイム・クラッシュ数(オーバーレイを有効にしているユーザー)
確認箇所 オーバーレイをすべてオフにして同じ場面のPresentMonのフレームタイムを比較し、クラッシュがあればイベントビューアーのイベントID 1000にある、障害が発生しているモジュールの名前(Faulting module name)を確認 該当する場合 オーバーレイをオフにすると一瞬の停止・グラフィックの不具合が消えるか、クラッシュの障害モジュールがオーバーレイソフトのDLL 該当しない場合 オーバーレイをすべてオフにしても同じなら、グラフィックドライバーか「クライアントのクラッシュ」 確認手段 ユーザー側の環境で確認
もっと詳しく 特定の人だけがカクついたりゲームが落ちたりして、スペックでは説明がつかないときは、まずオーバーレイとゲームのセキュリティモジュールの衝突を疑います。
出典3件
ディスプレイ・入力デバイス・フレーム生成による遅延 Display, input device and frame generation latency
ID co-display-input · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
Pingは正常なのに操作が重いなら、テレビの映像処理やワイヤレスコントローラー、フレーム生成機能が、入力と画面の間に遅延を上乗せしているのかもしれません。
なぜ テレビのゲームモードがオフ、Bluetooth・ワイヤレスコントローラーを使用、フレーム生成(DLSS・FSRのフレーム生成)が有効、のいずれか → すると テレビは画質処理をしている間フレームを遅れて出力し、ワイヤレス入力は送信周期と干渉の分だけ遅れて届き、フレーム生成は次のフレームを待ってから中間フレームを作る → 画面では PingとFPSの数字はよいのに、押してから画面に反映されるまでが遅く、入力遅延になる
症状 入力遅延
要因 遅延
誰に起きるか 自分だけ
いつ 常に
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 フレーム生成は選択式のオプションにして、有効にすると入力遅延が増えることがあると案内、フレーム生成を使うときはGPUメーカーの低遅延機能(NVIDIA Reflex、AMD Anti-Lag 2)もあわせて組み込む、ゲーム内でPC側の入力〜画面の遅延を表示、Android TV・セットトップボックス向けビルドではWindow.setPreferMinimalPostProcessing(true)でテレビに低遅延モード(ALLM)を要求。
外部の対応 ユーザーに、テレビ・モニターのゲームモード(ALLM)を有効にすること、競技性の高いコンテンツでは有線コントローラーを使いフレーム生成をオフにすること、Bluetooth機器は近くに置きWi-Fiは5GHzを使うことを案内。
数値の目安 60Hzの画面は1フレームを送るだけで16.7ms、120Hzなら8.3msかかります。以前のXboxコントローラーは8msごとに入力を読み取って送っていました。テレビの映像処理が加える遅延は機種ごとに異なり一つの数字では言えませんが、ゲームモードはこの処理を減らす設定です。フレーム生成は、生成前のフレームレートが60FPS以上の状態で使うようAMDが推奨しています。
グラフでは 最初から常に高い · 入力〜画面の遅延
確認箇所 PresentMonのMsAllInputToPhotonLatency(キーボード・マウスの入力から画面への出力まで)を、フレーム生成のオン・オフで比較し、FrameType(ドライバー・SDKが通知する場合にだけ記録)で、生成された中間フレームが混じっているかを確認。この値にはコントローラーの無線区間とテレビ内部の処理が含まれないため、その部分はテレビのゲームモード・有線コントローラーに切り替えながら比較 該当する場合 Pingは正常で、フレーム生成をオフにすると入力〜画面の遅延が減るか、テレビのゲームモード・有線コントローラーに切り替えると体感の遅延が消える 該当しない場合 これらの設定をすべて変えても同じで、Pingが高いか跳ねるならネットワーク側。PC側の遅延がV-Sync・フレームキューのせいで高いなら「V-Syncとレンダーキュー」 確認手段 ユーザー側の環境で確認
もっと詳しく ネットワークの遅延はPingで見えますが、この遅延はPingには表れません。そのため「Pingは低いのにラグい」という報告で、まず確認すべきところです。フレーム生成は画面のFPSの数字を2倍ほどに上げますが、中間フレームを作るには次の本物のフレームを待つ必要があるため、入力が画面に反映されるまでの時間は延びます(AMDは設計上遅延が増えると明言)。Bluetooth機器はWi-Fiと同じ2.4GHz帯を使うため、干渉を受けると入力が途切れたり飛んだりすることがあります。PC内の遅延を大きくするV-Sync・レンダーキューについては、「V-Syncとレンダーキュー」の項目を見てください。
出典9件
L3 家庭内ネットワーク
原因10件 · メインページの章
Wi-Fiの干渉・電波の弱さ Wi-Fi interference, weak signal
ID hn-wifi · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
電波が弱かったり干渉があったりすると、無線区間で何度も送り直すことになり、パケットの到着がばらつきます。
なぜ 壁・距離・電子レンジ・Bluetooth・近所のルーターによる電波品質の低下 → すると 無線区間で送信に失敗 → 何度も再送 → 画面では パケットの到着がばらつき(ジッター)、キャラクターが何度も一瞬止まる。ひどいとパケットロスでワープ
症状 カクつき , ワープ , 引き戻し
要因 ジッター, パケットロス
誰に起きるか 自分だけ, 同じ家
いつ ときどきランダムに, 常に
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 回線状態に応じて補間バッファの長さを自動調整、ジッター・パケットロスが大きければ画面にネットワーク状態を表示。
外部の対応 ユーザーに、有線接続、5GHz・6GHzの使用、ルーターの設置場所の変更を案内。
数値の目安 再送1回ごとに1〜4msほど余計にかかります。電波が弱いと遅い速度で何度も送り直し、チャンネルが空くまで待つこともあるため、50〜200msずつ跳ねることもあります。平均Pingは正常に見えるのが落とし穴です。
グラフでは 不定期なスパイク · ルーターまでのRTT
確認箇所 ping /tでルーターのアドレス(ipconfigのデフォルトゲートウェイ)を数分間測り、netsh wlan show networks mode=bssidで自分のルーターの電波強度・チャンネルを確認。同じ場所で有線に切り替えて比較 該当する場合 ルーターまでのPingの段階で不規則に数十〜数百ms跳ね、ときどきパケットロスが出て、電波強度が低い。有線やルーターの近くでは消える 該当しない場合 ルーターまでは安定していて、その先だけ跳ねるなら回線・通信事業者の区間。一定の間隔でだけ跳ねるなら「Wi-Fiのバックグラウンドスキャン」 確認手段 ユーザー側の環境で確認
もっと詳しく メッシュWi-Fiでルーター(ノード)同士が無線でつながっている場合(無線バックホール)、中継するノードは受信中に送信できず、同じチャンネルを使う前後の区間と送信の機会を分け合うため、混雑時にはスループットが落ち、遅延が増えることがあります。バックホール専用の無線帯域がある製品は影響が小さいことがあり、ノード同士を有線(イーサネット)でつなげば、この区間は無線を通らなくなります。電力線通信アダプター(PLC)もWi-Fiと同じく、媒体が空いているかを確かめてから送る方式(CSMA/CA)を使います。家電製品が出すノイズや家電製品の電源のオン・オフによって品質が絶えず変わるため、再送とジッターが生じることがあります。
実際の事例 Square Enix 2021: FINAL FANTASY XIVの拡張パッケージ発売時の混雑とログイン待機列のエラー
出典8件
ID hn-channel · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
マンションのようにルーターが数十台ある場所では、同じチャンネルを分け合って使うため、送信の機会を待つことになります。
なぜ 数十台のルーターが同じ2.4GHzのチャンネルを使用 → すると 送信するには、他の機器の送信が終わってチャンネルが空くまで待機 → 画面では 人が帰宅する夜の時間帯にジッター(到着間隔のばらつき)が増え、カクつき
症状 カクつき , 入力遅延
要因 ジッター, 遅延
誰に起きるか 同じ家
いつ 夜のピーク時間帯
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 ジッターが増えたら補間バッファの長さを自動で延ばす。
外部の対応 ユーザーに、5GHz・6GHz、混雑の少ないチャンネル、有線接続を案内。
グラフでは 特定の時間帯だけ高い · ルーターまでのRTT・ジッター
確認箇所 netsh wlan show networks mode=bssidで周囲のWi-Fiのチャンネルと電波強度を確認し、夜と昼にルーターまでのPingを測って比較 該当する場合 2.4GHzの同じチャンネルに周囲のルーターが多く見え、ルーターまでのジッターが夜の時間帯だけ大きくなる。5GHz・6GHzや混雑の少ないチャンネルに移ると減る 該当しない場合 時間帯に関係なく跳ねるなら「Wi-Fiの干渉・電波の弱さ」。ルーターまでは問題なく、夜にその先だけ悪いなら「ピーク時間帯のピアリング混雑」 確認手段 ユーザー側の環境で確認
出典4件
ID hn-bufferbloat · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
家族の誰かが動画をアップロードしたり大きなファイルをダウンロードしたりすると、ルーターのキューに数百ms分のパケットがたまり、ゲームのパケットもその後ろで待たされます。
なぜ 家族の動画アップロード・クラウドバックアップ、自分の配信、大容量ダウンロードで回線がいっぱいになる → すると ルーターやモデムが、あふれたパケットを大きなキューにためておく → 画面では ゲームのパケットもキューの後ろで待たされ、Pingが数百msまで急上昇
症状 入力遅延 , 早送り , ワープ
要因 遅延, ジッター
誰に起きるか 同じ家, 自分だけ
いつ ときどきランダムに, 夜のピーク時間帯
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 Pingが急に数百msまで上がったら画面にネットワーク状態を表示(同じ回線で大容量の転送をしている可能性を案内)。
外部の対応 ユーザーに、SQM(fq_codel、CAKE)やQoSのあるルーターの使用、SQMの速度を回線速度の90〜95%に設定すること(こうするとキューがルーターの中にでき、効果が出る)、上りの速度制限を案内。
数値の目安 上り10Mbpsの回線に1MBのバッファがあると、キューは800ms分まで長くなります。
グラフでは 人数・負荷に連動して上昇 · RTT、回線の上り・下りの使用量
確認箇所 Pingを実行したまま速度テストで回線をいっぱいにしてみるか、負荷中の遅延を測るWebテストを使う(Bufferbloat.netの案内)。ルーターの管理画面にある上り・下りの使用量とあわせて確認 該当する場合 上りか下りが回線を埋めている間、Pingが数百msまで上がり、転送が終わると戻る(負荷中の遅延が50msを超えたら疑う)。SQMを有効にすると消える 該当しない場合 回線が空いているのにPingが跳ねるなら「Wi-Fiの干渉・電波の弱さ」か「回線品質の不良」 確認手段 ユーザー側の環境で確認
もっと詳しく 特に詰まりやすいのは上り側です。ケーブル回線やモバイル回線は、上りが下りよりずっと細いことが多いためです。光回線に余裕のある家では、Wi-Fi区間がボトルネックになり、ルーターの無線キューで同じことが起きます。ゲームのパケットは小さいので帯域幅はほとんど使いませんが、キューで待たされる点は同じです。上り方向だけが詰まると、自分の入力だけが遅れ、他人の動きは正常です。スマホでは、同じスマホの写真バックアップやアプリの更新がスマホのモデムと基地局のキューを埋め、同じことが起きます。
出典4件
ID hn-nat · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ルーターは、しばらくパケットがやり取りされていないアイドル接続をNATテーブルから削除します。しばらく放置した後、動いた瞬間に切断されるときによくある原因です。
なぜ ルーターが「内側の機器 ↔ 外側のサーバー」の接続をNATテーブル(アドレス変換表)に記録 → すると パケットがしばらくないとテーブルから削除(UDPは30〜120秒が多い) → 画面では サーバーのパケットが家の中に入れず、切断
症状 切断
要因 パケットロス
誰に起きるか 自分だけ, 同じ家
いつ しばらく放置した後
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:最も短いアイドルタイムアウトの半分以下の間隔でハートビートを送る(UDPのマッピングは家の中から出ていくパケットでしか確実に更新されないため、クライアントが送る)、切れたら自動再接続。サーバー:ハートビートに応答し、一定時間受信がなければ先に接続を片付ける。マッピングが消えて外側のアドレス・ポートが変わっても、セッショントークン(接続時に受け取った確認用の番号)で同じプレイヤーであることを確かめて引き継ぐ。
グラフでは 接続が一斉に切れる · 切断数(ハートビートのタイムアウト)、切断前のアイドル時間
確認箇所 サーバーの切断理由と、切断前にその接続で最後のパケットがやり取りされてから経過した時間(アイドル時間)を集めて分布を確認。テストでは、UDPパケットの間隔を30秒・60秒・120秒と延ばしながら、応答が途切れる間隔を測定 該当する場合 放置していた接続だけが切れ、アイドル時間が30〜120秒のような特定の値の直後に集中する。ハートビートの間隔をそれより短くすると消える 該当しない場合 動いている最中にも切れるなら回線・経路側。特定のモバイルキャリアだけで短い値に集中するなら「通信事業者の共有IP(CGNAT)」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ルーターの性能不足・過熱 Router CPU / session table exhaustion
ID hn-router · 主担当 外部・外部
安価なルーターに数十台の機器、数千の接続が集中すると、ルーター自体が処理しきれなくなります。
なぜ 数十台の機器、P2P・トレントが数千の接続を開く → すると ルーターのCPUとセッションテーブルが飽和 → 画面では パケット処理の遅延・パケットロス、新しい接続の失敗
症状 カクつき , 接続不可・無限ロード , 切断
要因 パケットロス, ジッター
誰に起きるか 同じ家
いつ 長時間稼働するほど, ときどきランダムに
担当 主担当 外部・外部
外部の対応 ユーザーに、ルーターの再起動(一時的な対処)、ルーターの交換、接続を多く開くプログラム(P2P・トレント)の整理を案内。
グラフでは 上限で頭打ち · ルーターのCPU・接続数、ルーターまでのRTT
確認箇所 ルーターの管理画面でCPU使用率・接続(セッション)数・接続中の機器数を確認し(対応しているルーターなら)、ルーター自体までのPingを再起動の前後で比較 該当する場合 接続数が多いときにルーターまでのPingの段階で跳ねたりパケットロスが出たりし、新しい接続が失敗する。再起動するとしばらくは問題ないが、また悪くなる 該当しない場合 ルーターまでは問題なく、その先だけ悪いなら回線・通信事業者の区間 確認手段 ユーザー側の環境で確認
出典2件
ID hn-handover · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
バスや地下鉄で移動すると、基地局が切り替わる間、通信が途切れます。
なぜ 移動に伴い、接続する基地局が切り替わる → すると 通常は数十msの空白だが、電波が悪く切り替えに失敗すると数百ms〜数秒途切れることもある → 画面では 止まった後にワープ、長いと切断
症状 フリーズ , ワープ , 切断
要因 パケットロス
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:短い途切れに耐えるタイムアウト、素早い再接続。サーバー:数秒途切れてもすぐには追い出さないタイムアウト、再接続したら同じセッションで引き継ぐ。
外部の対応 移動中(バス・地下鉄)の切断は基地局の切り替えが原因であることをユーザーに案内。
グラフでは 途切れた後にまとめて到着 · 受信パケット数、RTT
確認箇所 切断の報告が移動中(バス・地下鉄)のものかを確認し、クライアントログにある受信の空白の時刻と、ネットワーク種別・電波の変化を確認 該当する場合 移動中だけ受信が数百ms〜数秒途切れた後にまとめて届き、止まっているときは再現しない 該当しない場合 止まっていても同じなら「モバイル電波の弱さ・不感地帯」か「5G↔LTEの頻繁な切り替え(5Gエリアの境界)」 確認手段 ユーザー側の環境で確認
出典2件
ID hn-rrc · 主担当 ゲーム開発チーム・クライアント開発
スマホはしばらく通信がないと無線接続を低電力状態に落とし、次のパケットのときに再び立ち上げるため遅れます。
なぜ しばらく通信がないと、スマホが無線接続を省電力状態に切り替える → すると 次のパケットを送るには、接続を再び立ち上げる必要がある → 画面では しばらく放置した後の最初の操作だけが特に遅い
症状 入力遅延
要因 遅延
誰に起きるか 自分だけ
いつ しばらく放置した後
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 軽い定期送信でアクティブ状態を維持(バッテリー消費とのトレードオフ)。
数値の目安 LTEは通常10秒前後通信がないと省電力状態に落ち、復帰には数十〜数百msかかります(実測例:約0.3〜0.6秒)。3Gは1秒以上。
グラフでは 一部だけ高い · アイドル後の最初のリクエストのRTT(モバイル)
確認箇所 ゲーム内のRTTを、直前の通信からの間隔ごとに分けて確認。モバイルで10秒以上休んだ後に送った最初のパケットと、連続して送ったパケットのRTTを比較 該当する場合 モバイル回線で休んだ後に送った最初のパケットだけが数百ms遅れ、すぐ続けて送ったパケットは正常。Wi-Fiでは差がない 該当しない場合 連続して送っても遅いなら電波・回線・経路側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID hn-weak-cell · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
エレベーター・地下・建物の奥では、再送が増えて速度が落ち、最終的に切断されます。
なぜ 電波の弱い場所へ移動 → すると 無線区間の再送の増加、速度の低下、瞬断 → 画面では ジッター・パケットロスでカクつき・ワープ、最終的に切断
症状 カクつき , ワープ , 切断
要因 ジッター, パケットロス
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 再接続の流れの改善、ネットワーク品質の表示。
外部の対応 電波の弱い場所(エレベーター・地下・建物の奥)で起きる問題であることをユーザーに案内。
グラフでは 一部だけ高い · RTT・パケットロス(モバイルユーザー別)
確認箇所 切断報告時の場所(エレベーター・地下・建物の中)とスマホの電波表示を確認し、電波の良い場所で同じ操作を繰り返して比較 該当する場合 電波の弱い場所でだけRTT・パケットロスが増えて切れ、電波の良い場所に移ると消える 該当しない場合 電波が良いのに同じなら通信事業者の区間かサーバー側 確認手段 ユーザー側の環境で確認
出典1件
ID hn-5g-flip · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
5Gの電波が弱い建物の中や5Gエリアの境界では、スマホが5GとLTEを頻繁に行き来し、切り替わるたびにPingが跳ねたり通信が一瞬途切れたりします。
なぜ 5Gの電波が不安定な場所(建物の中、5Gエリアの境界)にいる → すると スマホが5GとLTEの間を頻繁に切り替え、そのたびに短い空白が生じる → 画面では 動かずにいても不規則にPingが跳ね、ときどきフリーズ・ワープ
症状 カクつき , ワープ , フリーズ
要因 ジッター, パケットロス
誰に起きるか 自分だけ
いつ ときどきランダムに, 移動中・マップ切り替え時
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 ジッターが増えたら補間バッファの長さを自動で延ばす。ラグが起きたときのログにネットワーク種別(5G・LTE)の変化もあわせて記録し、原因を区別。
外部の対応 ユーザーに、設定でLTE優先モードに切り替えて比較してみるよう案内、Wi-Fiの使用を推奨。
数値の目安 切り替え1回あたり数十〜数百ms。韓国の5Gは大半がLTEと組み合わせて使う方式(NSA)のため、5G側だけがつながったり外れたりしやすくなっています。
グラフでは 不定期なスパイク · RTT、ネットワーク種別(5G・LTE)の変化
確認箇所 スマホの設定をLTE優先に切り替え、同じ場所で比較。クライアントがAndroidのTelephonyDisplayInfoのネットワーク表示(OVERRIDE_NETWORK_TYPE_NR_NSAなど)の変化をRTTとあわせて記録すれば、より確実 該当する場合 RTTが跳ねた時刻と5G↔LTEの表示が変わった時刻が重なり、LTE優先モードではスパイクが消える 該当しない場合 ネットワーク表示が変わらないのに跳ねるなら「モバイル電波の弱さ・不感地帯」か回線側 確認手段 ユーザー側の環境で確認
出典3件
ID hn-captive · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
カフェのWi-Fiのログインページや会社のファイアウォールが、ゲームの接続をブロックします。
なぜ ログインページでの認証前か、ファイアウォールがゲームのポート・UDPを遮断 → すると 接続の試み自体がブロックされるか、一部だけが通る → 画面では 接続不可、ログインはできるのにゲームに入れない
症状 接続不可・無限ロード
要因 パケットロス
誰に起きるか 自分だけ
いつ 接続直後・メンテ明け
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:ブロックされたときに理由を伝える案内(ログインページでの認証前、UDPの遮断など)、UDPがブロックされたら代替経路へ自動で切り替え。サーバー:TCP 443などの代替経路を提供。
外部の対応 ユーザーに、公衆Wi-Fiではまずログインページで認証し、社内ネットワークのように制限された場所では別のネットワークを使うよう案内。
グラフでは 一部だけ高い · 接続失敗数(ネットワーク別)
確認箇所 失敗したユーザーにモバイルデータ通信など別のネットワークに切り替えて接続してもらい、サーバーの接続ログで、UDPの最初のパケットが届いたかと、TCP 443の代替経路ならつながるかを確認 該当する場合 特定のWi-Fi(カフェ・会社)でだけ失敗し、ほかのネットワークではすぐつながる。ログインページでの認証前か、UDPだけがサーバーに届かない 該当しない場合 どのネットワークでも失敗するならアカウント・サーバー・「DNSの障害・遅延」側。特定の国・通信事業者全体で失敗するなら「国・通信事業者単位のUDP制限・パケット検査」 確認手段 ユーザー側の環境で確認
出典2件
L4 インターネット回線
原因14件 · メインページの章
ID isp-distance · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・ネットワークインフラ, ゲーム開発チーム・サーバー開発
光ファイバーの中では、光でさえ1秒に約20万kmしか進みません。遠いサーバーは、どれほど性能が良くても遅れます。
なぜ サーバーが遠くにある(海外サーバー、別の大陸) → すると 距離の分だけ往復時間が延びる(1,000kmあたり最低10ms) → 画面では すべての操作に一定の入力遅延、判定で不利
症状 入力遅延
要因 遅延
誰に起きるか 特定の地域・ISP
いつ 常に
担当 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・ネットワークインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 物理法則はコードでは直せないため緩和のみ可能。近い地域のサーバーを選ばせる地域選択、ラグコンペンセーション(巻き戻し)による判定の不利の軽減。
インフラチームの対応 サーバー機器・OS:利用者の多い地域ごとにサーバーを置く。ネットワーク:近くに接続拠点(エッジ)を置く、遠回りの少ない回線・経路を選ぶ。
数値の目安 ソウル・東京間は約30ms、ソウル・シンガポール間は約75ms、ソウル・米国西海岸間は約140ms、ソウル・欧州間は約230〜270msです(往復、実際の経路での値)。欧州へは直線上に大容量のケーブルがほとんどなく、東南アジア・スエズ経由か米国経由で回り込むため、距離から見込むよりずっと長くなります。
グラフでは 最初から常に高い · RTT(国・地域別)
確認箇所 接続元IPに国情報を付けて国別のRTT分布を確認し、その地域のクラウドリージョンのVMやRIPE Atlasのプローブ(国・ASNで選択)からサーバーまでping・tracerouteで測定 該当する場合 遠い国のRTTが時間帯に関係なく常に高く、その値が距離から計算した最小遅延(1,000kmあたり往復10ms)や公開されている遅延統計に近い 該当しない場合 距離で説明できる値よりずっと高ければ「迂回ルーティング」、夜だけ上がるなら「ピーク時間帯のピアリング混雑」 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 Riot Games 2015: 遠回りしていたLeague of LegendsのトラフィックとRiot Direct
出典4件
ID isp-satellite · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
衛星インターネットは電波が宇宙を往復するため、静止軌道衛星では往復だけで0.5秒を超えます。Starlinkのような低軌道衛星は普段は速いものの、経路を割り当て直す瞬間に遅延が揺れ、一瞬途切れることもあります。
なぜ 自宅・船・飛行機から、静止軌道衛星や低軌道衛星のインターネット、衛星を使う機内Wi-Fiで接続 → すると 静止軌道は高度が約36,000kmあり、往復する距離そのものが長い。低軌道は端末・衛星・地上局の経路を短い周期で割り当て直し、その瞬間に遅延・パケットロスが一時的に発生 → 画面では 静止軌道はすべての操作に大きな入力遅延。低軌道は普段は問題ないが、一定の間隔でカクつき・ワープ
症状 入力遅延 , カクつき , ワープ
要因 遅延, ジッター, パケットロス
誰に起きるか 自分だけ, 同じ家, 特定の地域・ISP
いつ 常に, 一定の周期で
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:ジッターに合わせて補間バッファの長さを自動で延ばす、短いパケットロスに耐えられるよう入力を重複送信、接続品質の表示。サーバー:判定の受付時間やラグコンペンセーションの上限を決めるときに衛星回線の遅延を考慮、1秒前後の途切れですぐに切断しないタイムアウト。
外部の対応 ユーザーに、衛星インターネットは遅延が大きかったり周期的に跳ねたりすることがあると案内、対戦コンテンツではできるだけ地上の有線回線を使うよう案内。
数値の目安 静止軌道(高度36,000km)は、電波が宇宙を通過するだけで片道260ms、往復で520msを超えます(ITU-T G.114)。低軌道のStarlinkは、公式資料(15秒平均値)で米国のピーク時間帯の中央値が33ms、最も悪い1%(p99)でも65ms未満です(2024年)。測定研究では、15秒ごとに経路を割り当て直す瞬間に遅延が変わり、1秒未満の短い途切れが発生していました。2018年の機内インターネットの測定では、衛星方式の往復遅延は平均750msでした。
グラフでは 一部だけ高い · RTT・ジッター(衛星インターネット事業者のASN別)
確認箇所 接続元IPのASNが衛星インターネット事業者かを確認し、その事業者のユーザーだけでRTT分布と時系列を描画。そのASNのRIPE Atlasプローブからサーバーまでpingを数分間続けて測定するか、ユーザーにpingを実行したままにしてもらい、跳ねる間隔を測定 該当する場合 静止軌道の事業者はRTTが常に500msを超え、低軌道の事業者は普段は数十msで、約15秒間隔でRTTが変わるか短く途切れる 該当しない場合 衛星事業者ではないのにRTTが常に高ければ「伝搬遅延(物理的な距離)」か「迂回ルーティング」、不規則に跳ねるならWi-Fi・モバイルの電波側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 低軌道衛星は衛星までの距離が短いため(Starlinkの1区間で1.8〜3.6ms)、普段の遅延は地上回線と同程度になることもあります。ただし、地上局からインターネットに出る地点(PoP)がゲームサーバーから遠ければ、その分だけ経路が長くなり、衛星間のレーザーリンクを経由するとさらに遅延が加わります。測定研究では、15秒周期の揺れは衛星間の切り替えとは関係がなく、世界中で同じ時刻に行われる経路の再割り当てが原因だとみています。機内Wi-Fiは方式(衛星、地上の基地局)によって遅延が大きく異なり、静止軌道衛星を使う方式なら上記と同じ長い往復遅延が発生します。
出典5件
迂回ルーティング Suboptimal routing
ID isp-routing · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
通信事業者どうしの接続契約の都合で、近いサーバーでも遠くを回って届きます。
なぜ 自分の通信事業者とサーバー側の通信事業者が直接つながっていない → すると 別の国や別の都市を経由し、距離と経由する機器が増える → 画面では 特定の通信事業者のユーザーだけPingが際立って高い
症状 入力遅延
要因 遅延
誰に起きるか 特定の地域・ISP
いつ 常に
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
インフラチームの対応 複数の通信事業者と接続(マルチホーム)、通信事業者別のPingを監視して遠回りしている事業者を特定、通信事業者と経路の調整を協議。
外部の対応 該当する通信事業者に経路の調整を依頼。
数値の目安 同じ国の中でも、経路によってPingが2〜3倍違うことがあります。
グラフでは 最初から常に高い · RTT(通信事業者・ASN別)
確認箇所 通信事業者(ASN)別にRTTを比較し、遅い事業者のRIPE Atlasプローブやユーザーから受け取ったtraceroute・mtrで、経路がどの国・都市を経由しているかを確認。IPv4とIPv6は別々に測定(mtr -4、-6) 該当する場合 同じ地域なのに特定の通信事業者だけが常に高く、経路に別の国や遠い都市を経由する区間がある。または一方のアドレスファミリー(IPv4かIPv6)だけが高い 該当しない場合 すべての通信事業者が同じように高ければ「伝搬遅延(物理的な距離)」、夜だけ高ければ「ピーク時間帯のピアリング混雑」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく IPv4とIPv6は経路が別々に決まるため、同じサーバーでも片方だけが遠回りして遅くなることがあります(2016年のAPNICの測定:同じ通信事業者の中に、IPv6がIPv4より15・25・75ms遅いユーザー集団がそれぞれ現れた)。IPv6とIPv4のうち先につながった方を使うHappy Eyeballs(RFC 8305)方式のアプリは、IPv6を先に試し、IPv6が推奨値の250ms以内につながればIPv4は試しません。そのため、IPv6側が少し遅くても、その経路で接続しやすくなります。特定の通信事業者だけPingが高いときは、IPv4とIPv6を分けて測定します。
実際の事例 Riot Games 2015: 遠回りしていたLeague of LegendsのトラフィックとRiot Direct
出典6件
ピーク時間帯のピアリング混雑 Peak-hour congestion at peering
ID isp-peak · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
夜9〜11時ごろは動画のトラフィックが急増し、通信事業者間の接続区間(ピアリング)が混雑しやすくなります。
なぜ 夜の時間帯にストリーミング・ダウンロードが集中 → すると ピアリング区間でキューの滞留とパケットロスが発生 → 画面では 夜だけ、特定の通信事業者のユーザーにカクつき・ワープ
症状 カクつき , ワープ , 引き戻し
要因 ジッター, パケットロス, 遅延
誰に起きるか 特定の地域・ISP
いつ 夜のピーク時間帯
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
インフラチームの対応 該当する通信事業者との直接接続を増やす、混雑した経路の迂回、通信事業者別に夜間のパケットロス・Pingを監視。
外部の対応 該当する通信事業者にピアリング区間の増強を依頼。
グラフでは 特定の時間帯だけ高い · RTT・パケットロス(通信事業者別)
確認箇所 通信事業者(ASN)別にRTT・パケットロスを時間帯ごとに描画し、その事業者のRIPE Atlasプローブやユーザーから夜と昼それぞれのmtrを受け取り、パケットロスが始まる区間を確認 該当する場合 特定の通信事業者だけ毎晩9〜11時ごろにRTT・パケットロスが上がり、mtrで通信事業者間の接続区間から宛先までパケットロス・遅延が続く 該当しない場合 すべての通信事業者で一緒に上がるなら自社の回線・サーバー側。同じ家だけ夜に悪ければ「Wi-Fiチャンネルの混雑」 確認手段 インフラのツールで確認(ゲームコード不要)
出典2件
ID isp-cable · 主担当 外部・外部 · 副担当 インフラチーム・ネットワークインフラ
海底ケーブルが切れると、修理されるまでの数週間(長ければ数か月)は遠い迂回経路を回ることになり、残った回線は混雑します。
なぜ ケーブルの切断・機器の故障 → すると トラフィックが遠い迂回経路と残った回線に集中 → 画面では 海外からの接続者でPingの急上昇とパケットロスが数日〜数週間続く
症状 入力遅延 , ワープ
要因 遅延, パケットロス
誰に起きるか 特定の地域・ISP
いつ 常に
担当 主担当 外部・外部 · 副担当 インフラチーム・ネットワークインフラ
インフラチームの対応 別経路の回線の確保、障害時にトラフィックをその経路へ移す。
外部の対応 海外からの接続者に原因と復旧見込みを告知、回線事業者に復旧スケジュールの確認を依頼。
グラフでは ある時点から階段状に上昇 · RTT(海外の国別)
確認箇所 国別のRTT・パケットロスのグラフで上昇した時刻を探し、Cloudflare Radarのインターネット障害のまとめや海底ケーブル事業者の告知と照合。tracerouteで経路が別の大陸を回っていないか確認 該当する場合 ある時点から特定の海外地域のRTTが一段上がって数日〜数週間とどまり、同じ時期にケーブル障害の報告がある。経路が普段と違う遠い迂回経路に変わっている 該当しない場合 数日以内に元に戻り、障害報告がなければ「BGPの経路変更・収束」か通信事業者の区間 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
BGPの経路変更・収束 Route change / BGP convergence
ID isp-bgp · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
インターネットの経路情報が変わり、再び収束するまでの数秒〜数十秒(まれに数分)の間、パケットが失われます。
なぜ どこかの通信事業者の区間で経路情報が変わる → すると 数秒〜数十秒の間パケットが消えるか、新しい経路に切り替わる → 画面では 突然数秒止まった後、Pingの値が変わる(例:40→70ms)
症状 フリーズ , ワープ
要因 パケットロス, 遅延
誰に起きるか 特定の地域・ISP
いつ ときどきランダムに
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
ゲーム開発チームの対応 短い途切れに耐えるタイムアウト(数秒止まった接続をすぐに切らない)。
インフラチームの対応 経路の監視(自社IPアドレス帯の経路・Pingの変化を監視)、自社回線の障害はBFDで1秒以内に検知して切り替え(BGPのデフォルトのホールドタイムは90〜180秒)、遠い経路に変わったまま戻らなければ別の回線にトラフィックを移す。
外部の対応 経路が頻繁に変わる通信事業者の区間は、その通信事業者に原因の確認を依頼。
グラフでは ある時点から階段状に上昇 · RTT、tracerouteの経路
確認箇所 RTTが変わった時刻の前後でtraceroute・mtrの経路を比較し、RIPEstatのBGPlayで自社アドレス帯(prefix)のBGP経路変更の履歴を確認 該当する場合 数秒の停止と同時にRTTが別の値に移り、同じ時刻にBGPアップデートとAS経路の変更がある 該当しない場合 経路変更の履歴がないのに夜だけ上がるなら「ピーク時間帯のピアリング混雑」、一部の接続だけ悪ければ「ECMP経路のうち1本の不良」 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 Cloudflare 2020: Cloudflareのバックボーン設定ミスで一部都市のトラフィックが途絶 Meta 2021: バックボーンへのコマンド一つでDNSまで消えたFacebookの障害 Cloudflare 2025: CloudflareのパブリックDNS 1.1.1.1の障害
出典4件
ECMP経路のうち1本の不良 ECMP / link bundle member fault
ID isp-ecmp · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
通信事業者やデータセンターは同じ宛先への経路を複数持ち、接続ごとに1本の経路を決めて送ります。1本の経路だけが故障すると、その経路に割り当てられた人だけにラグが出続けます。
なぜ 複数の回線を束ねた区間で、1本の回線や1台の機器が不良、または混雑 → すると アドレス・ポートの組み合わせ(ハッシュ)で経路が決まり、その経路に割り当てられた接続だけにパケットロス・遅延 → 画面では 同じ地域・同じ通信事業者なのに一部の人だけが継続的にワープ。再接続すると直ることもある
症状 ワープ , 引き戻し , カクつき
要因 パケットロス, ジッター
誰に起きるか 自分だけ, 特定の地域・ISP
いつ 常に
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
ゲーム開発チームの対応 接続ごとのパケットロス・再送の統計を残し、影響を受けている人のIP・ポートと時刻を抽出できるようにする(TCPはTCP_INFOの再送回数、UDPは抜けたパケットのシーケンス番号から計算)。
インフラチームの対応 影響を受けている人のIP・ポートと時刻を集めて通信事業者・データセンターに伝える、経路ごとのパケットロス監視、経路の測定はゲームと同じプロトコル・ポートで行う(mtr --tcp・--udpと--port)、自社機器の経路なら不良の回線・機器を束から外す。
外部の対応 通信事業者に不良経路の確認・交換を依頼、ユーザーには再接続で一時的に回避するよう案内(再接続でポートが変わる場合)。
数値の目安 経路が4本なら、影響を受けるのはユーザーの約4分の1だけです。Pingの測定はゲームとは別の経路を通るため、正常な値が出ることもあります。
グラフでは 一部だけ高い · 接続ごとのパケットロス・再送(IP・ポート別)
確認箇所 接続ごとのパケットロス・再送を送信元IP・ポートで分けて確認。mtrをUDP(-u)でゲームのポート(-P)宛てに送り、送信元ポート(-L)を固定して測定し、送信元ポートを変えて何度か繰り返す。-Lを付けずに-Pだけを指定すると、要求ごとに送信元ポートが変わって複数の経路が混ざる 該当する場合 同じ地域・通信事業者の中で、特定の送信元ポート(またはアドレス)の組み合わせだけで継続的にパケットロスが発生し、再接続してポートが変わると直る 該当しない場合 ポートを変えてもすべて悪ければ、ある区間全体の混雑・障害 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 1つの接続のパケットの順序が入れ替わらないよう、機器はアドレスとポート(機器の設定によってはアドレスだけ)から計算した値で、接続ごとに経路を固定します(ECMP、LAG)。アドレスだけを使う環境では、再接続しても同じ経路になるため改善しません。そのため「Pingは正常なのにゲームだけラグい」「再接続したら直った」といった報告が一緒に届いたら、この原因を疑います。
出典3件
ID isp-shaping · 主担当 外部・外部 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
データ使用量の上限を超えた場合や、特定のトラフィックを管理する料金プランでは、パケットが遅らされたり破棄されたりします。
なぜ 料金プランのデータ容量を使い切った後の速度制限、または特定トラフィックの制限 → すると パケットが待たされるか破棄される → 画面では 一定の使用量を超えた後にラグ、特にモバイル
症状 入力遅延 , ワープ
要因 遅延, パケットロス
誰に起きるか 自分だけ, 特定の地域・ISP
いつ 常に, 夜のピーク時間帯
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 ゲームのトラフィックを減らす(圧縮、必要なものだけ送信)。
インフラチームの対応 特定の通信事業者だけでゲームのトラフィックが遅らされたり破棄されたりしていれば、データを集めて通信事業者にエスカレーション。
外部の対応 ユーザーに、料金プランのデータ容量を使い切って速度制限がかかっていないか、同じスマホでほかのアプリを使っていないかを確認するよう案内、通信事業者にゲームトラフィックの制限の有無を問い合わせ。
数値の目安 韓国のモバイル料金プランでは、データ容量を使い切ると通常1〜5Mbps、安いプランでは数百kbpsに制限されます。ゲーム自体の通信量は少なくても、同じスマホのほかのアプリが通信すると、速度制限装置の手前にキューができます。
グラフでは 上限で頭打ち · スループット、RTT
確認箇所 ユーザーにキャリアのアプリで残りのデータ容量と速度制限の有無を確認してもらい、速度テストで最大速度を確認。サーバー側では通信事業者別のパケットロス・RTTを比較 該当する場合 スループットが1〜5Mbpsや数百kbpsといった一定の値から上がらず、その状態で同じスマホのほかのアプリが通信するとRTT・パケットロスが増える。データ容量を追加するかWi-Fiに切り替えると消える 該当しない場合 速度制限がないのに特定の通信事業者だけ悪ければ「ピーク時間帯のピアリング混雑」か「迂回ルーティング」 確認手段 ユーザー側の環境で確認
出典2件
国・通信事業者単位のUDP制限・パケット検査 UDP blocking, throttling and inspection by networks
ID isp-udp-block · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
一部のネットワークでは、特定のUDPアドレス・ポートをブロックしたりUDPの速度を制限したりし、パケット検査装置が識別できないプロトコルを遮断します。UDPで通信するゲームは、そのネットワークでは接続できなかったり、頻繁に切断されたりします。
なぜ UDPの速度を制限する一部の通信事業者網や、国・通信事業者単位のトラフィック検査(検閲)装置があるネットワークから接続 → すると 特定のUDPアドレス・ポートをブロック、混雑する時間帯にUDPの速度を制限、許可リストにないポート・プロトコルを遮断、または最初の数パケットだけ通してからブロック → 画面では 特定の国・通信事業者のユーザーだけ接続不可・無限ロード、接続してもすぐに切断、混雑する時間帯にパケットロスでワープ
症状 接続不可・無限ロード , 切断 , ワープ
要因 パケットロス
誰に起きるか 特定の地域・ISP
いつ 接続直後・メンテ明け, 常に, 夜のピーク時間帯
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 クライアント:UDPが数秒以内につながらなければTCP・TLS 443の代替経路に自動で切り替える、最初はつながってもすぐ切れるケースも検知して代替経路で再試行、どの経路で接続したかをログに残す。サーバー:同じゲームプロトコルをTCP 443(TLS)でも受け付ける、代替経路は遅延が増えることがあるのでタイムアウトを調整。
インフラチームの対応 海外の国・地域を追加する前に、現地の通信事業者網でUDPの到達可否とピーク時間帯のパケットロスを測定、TCP 443の代替経路を受けるリレー・ゲートウェイを現地の近くに置く、国・ASN別にUDP・TCPの接続成功率を監視、UDPの速度制限が確認された通信事業者はデータを集めてエスカレーション。
外部の対応 該当する通信事業者・機関にUDP制限の基準と緩和について問い合わせ、ユーザーには別のネットワークから接続して比較してみるよう案内。
数値の目安 IETFの文書が引用した測定によると、ネットワークの3〜5%はUDPを完全にブロックしています。Googleが2016年にQUIC(UDPベース)の利用状況を調べたところ、クライアントの4.4%はUDP・QUICがブロックされているか経路MTUが小さいために使えず、その大半は企業のファイアウォールの内側でした。通信事業者全体でブロックしている例は見られませんでした。0.3%はピーク時間帯にパケットロスが大きく増える、UDPの速度を制限しているとみられるネットワークにあり、通信事業者に要請して2015年の1%から減らしました。
グラフでは 一部だけ高い · UDP接続成功率(国・ASN別)
確認箇所 国・ASN別にUDPの接続成功率とTCP 443の代替経路の成功率を分けて確認。該当する通信事業者網のクラウドVMやユーザーのPCから、ゲームのUDPポートとTCP 443でそれぞれ接続試験を行い、mtr -u -P(ゲームのポート)とmtr -T -P 443で、どの区間から応答が消えるかを比較 該当する場合 特定の国・ASNだけでUDPの最初の応答がないか数秒で切れ、同じ場所からのTCP 443は正常。速度制限の場合は、ピーク時間帯にだけUDPのパケットロスがはっきり増え、TCPへの影響は小さい 該当しない場合 TCPも一緒に失敗するなら経路障害・IPブロック・「DNSの障害・遅延」側。すべての国で同じなら自社のサーバー・ファイアウォールの設定、UDP・TCPを問わず瞬間的な送信量が多いときだけパケットロスが出るなら「ポリサーによる超過分の破棄」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく パケット検査装置は、アドレス・ポート・プロトコルでUDPのフローを選んでブロックしたり、許可したプロトコル以外はすべてブロックする方式(許可リスト)を使ったりします(IRTFの調査文書)。装置がパケットの一部のフィールドだけを見て判断していると、プロトコルを少し変えただけでブロックされることもあります。QUICの初期には、あるファイアウォールがヘッダーの1ビットが変わった後、最初の数パケットは通してそれ以降のパケットをブロックしたため、クライアントがTCPに切り替えて接続するロジックが働きませんでした。海外の国・地域を追加したときに、「国内は問題ないのに、その国の一部の通信事業者だけ接続できない」という報告で発覚することがあります。カフェや会社のように、ある場所のネットワークだけでブロックされるなら「公衆Wi-Fi・社内ネットワークの制限」の項目を参照してください。
出典4件
回線品質の不良 Faulty last-mile line / modem
ID isp-line · 主担当 外部・外部
端子の接触不良や古いケーブル、モデムの異常は、継続的なパケットロスと周期的な回線断を引き起こします。
なぜ ケーブルの損傷、接触不良、モデム・ONU(光回線終端装置)の異常 → すると ビットエラーでパケットが破棄され、ときどき回線の再接続で数秒〜1分ほど途切れることもある → 画面では 継続的な少量のパケットロス、ときどき数秒のフリーズや切断
症状 ワープ , フリーズ , 切断
要因 パケットロス
誰に起きるか 同じ家
いつ ときどきランダムに
担当 主担当 外部・外部
外部の対応 ユーザーに、ほかのゲームやビデオ通話も途切れるかを確認し、途切れるなら通信事業者に点検を依頼するよう案内。
グラフでは 不定期なスパイク · パケットロス率、回線の再接続履歴
確認箇所 pathping(またはmtr)で通信事業者の最初の区間までのパケットロスを数分間測定し、ルーターの管理画面にあるインターネット(WAN)接続の履歴で再接続の時刻を確認 該当する場合 回線が空いているときでも通信事業者の最初の区間から継続的にパケットロスが出て、ルーターの履歴にある回線の再接続時刻がフリーズ・切断の時刻と重なる。ほかのゲームやビデオ通話も一緒に途切れる 該当しない場合 パケットロスがルーターまでの無線区間から始まっていれば「Wi-Fiの干渉・電波の弱さ」、通信事業者の遠い区間から始まっていれば通信事業者の経路 確認手段 ユーザー側の環境で確認
出典3件
DNSの障害・遅延 DNS failure / slowness
ID isp-dns · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
サーバー名をアドレスに変換するDNSが遅かったり失敗したりすると、ログインサーバーやアップデートサーバーを見つけられません。
なぜ 通信事業者のDNSの障害または設定ミス → すると ログイン・アップデートサーバーのアドレスが見つからない → 画面では 接続ボタンを押した後に長く待たされるか接続不可。すでに接続している人は問題ない
症状 接続不可・無限ロード
要因 遅延, パケットロス
誰に起きるか 特定の地域・ISP, 自分だけ
いつ 接続直後・メンテ明け
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 アドレスのキャッシュ(最後に接続に成功したサーバーのアドレスを記憶)、複数のDNSを用意(1つが失敗したら別のDNSに再度問い合わせ)。
外部の対応 ユーザーに、DNSをパブリックDNSなど別のものに変えてみるよう案内。
グラフでは 一部だけ高い · ログイン失敗数(通信事業者別)、DNSの問い合わせ時間
確認箇所 Resolve-DnsName -Server(またはnslookup)で、ログインサーバーの名前を通信事業者のDNSとパブリックDNSにそれぞれ問い合わせ、応答時間と結果を比較 該当する場合 通信事業者のDNSだけで応答がないか時間がかかり、パブリックDNSに変えるとすぐに接続できる。すでに接続しているユーザーは問題ない 該当しない場合 どのDNSでもアドレスはすぐに返るのに接続できなければ、経路・ファイアウォール・サーバー側 確認手段 ユーザー側の環境で確認
実際の事例 Meta 2021: バックボーンへのコマンド一つでDNSまで消えたFacebookの障害 Cloudflare 2025: CloudflareのパブリックDNS 1.1.1.1の障害 AWS 2025: AWS us-east-1のDynamoDB DNS障害と長引いた復旧
出典4件
DDoSによる共有回線の飽和 DDoS saturating shared links
ID isp-ddos-path · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
ゲーム会社や同じネットワーク内の別の宛先を狙った大量の攻撃が、共有回線を埋め尽くします。
なぜ 大量の攻撃トラフィックが発生 → すると 同じ回線を使う正常なトラフィックまで押し出されて破棄される → 画面では 多くの人が同時にワープ・切断・接続不可
症状 ワープ , 切断 , 接続不可・無限ロード
要因 パケットロス, 遅延
誰に起きるか サーバー全体, 特定の地域・ISP
いつ ときどきランダムに, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
インフラチームの対応 DDoS対策サービス、攻撃時のトラフィック迂回、サーバーのアドレスを隠す(防御機器の後ろに置き、実際のアドレスを公開しない)。
外部の対応 同じネットワーク内の別の宛先への攻撃なら、通信事業者に上流区間での遮断を依頼。
グラフでは 上限で頭打ち · 回線の受信量(bps・pps)、インターフェースのドロップ
確認箇所 自社の回線・機器のインターフェースの受信量と破棄したパケット数、DDoS対策サービスの攻撃検知履歴を、切断が集中した時刻と合わせて確認 該当する場合 回線の受信量が回線容量に張り付いて平らになり、ドロップが増え、同じ時刻に複数の地域・通信事業者のユーザーが一斉にワープ・切断 該当しない場合 回線に余裕があるのに一部の通信事業者だけ悪ければ、通信事業者区間の混雑・経路の問題 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID isp-cgnat · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
モバイル回線や一部の通信事業者では、複数の契約者が1つのIPを共有し、アイドル接続のマッピングを短時間で削除します。
なぜ 通信事業者の機器が膨大な数の契約者のセッションテーブルを管理 → すると セッションテーブルの上限、短いアイドルタイムアウト → 画面では しばらく放置した後に切断、同じIPを使う人たちがまとめてブロックされる誤検知
症状 切断 , 接続不可・無限ロード
要因 パケットロス
誰に起きるか 特定の地域・ISP
いつ しばらく放置した後
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 クライアント:最も短いアイドルタイムアウト(モバイル回線では30秒前後の場合もある)の半分以下の間隔でハートビートを送る(通信事業者のCGNATのマッピングは内側から出ていくパケットでしか確実に更新されないため、クライアントから送る)、切れたら自動で再接続。サーバー:ハートビートに応答し、一定時間受け取れなければ先に接続を整理、マッピングが変わってアドレス・ポートが変わってもセッショントークンで同じプレイヤーとして引き継ぐ、1つのIPを複数の人が共有していることがあるのでIP単位のブロックポリシーは慎重に(アカウント・端末単位と合わせて判断)。
インフラチームの対応 ファイアウォール・DDoS対策機器のIPあたりの接続数・毎秒の新規接続数の制限を、通信事業者の共有IPに合わせて調整(モバイル通信事業者のアドレス帯は基準を上げるか例外にする)。
数値の目安 モバイル回線のUDPのアイドルタイムアウトは、30秒前後の場合もあります。
グラフでは 接続が一斉に切れる · 切断数(ハートビートのタイムアウト)、切断前のアイドル時間(通信事業者別)
確認箇所 接続ログで1つのIPに同時に接続しているアカウント数と通信事業者(ASN)を確認し、アイドル後に切れた接続のアイドル時間を通信事業者別に集計。ユーザー側ではルーターの管理画面でインターネット(WAN)のアドレスを確認 該当する場合 モバイル通信事業者のアドレス帯で1つのIPに複数のアカウントが接続し、切断前のアイドル時間が30〜60秒前後の短い値に集中。ルーターのWANアドレスが100.64.0.0/10(通信事業者のNAT用の共有アドレス)か、サーバーから見えるアドレスと異なる 該当しない場合 通信事業者に関係なく家庭用ルーターのユーザーに集中していれば「NATマッピングの期限切れ」 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典4件
VPN・ラグ軽減ツール経由 VPN / game accelerator detour
ID isp-vpn · 主担当 外部・外部 · 副担当 インフラチーム・ネットワークインフラ, ゲーム開発チーム・サーバー開発
VPNやラグ軽減ツールを使うと、パケットはその会社の中継サーバーを経由します。中継サーバーが遠かったり混雑していたりすると、かえって遅くなります。
なぜ VPN・ラグ軽減ツールが、ゲームのパケットをすべて中継サーバーに回す → すると 中継サーバーまでの距離と混雑が加わり、トンネルのヘッダーのせいでMTU(一度に送れるパケットサイズ)も小さくなる → 画面では Pingの上昇とパケットロス、同じ中継アドレスを使う人と一緒にブロックされて接続不可
症状 入力遅延 , ワープ , 接続不可・無限ロード
要因 遅延, パケットロス
誰に起きるか 自分だけ
いつ 常に, 接続直後・メンテ明け
担当 主担当 外部・外部 · 副担当 インフラチーム・ネットワークインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 UDPパケットは1,200バイト以下に保つ(トンネルのヘッダーでMTUが小さくなってもフラグメント化しないように)、IP単位のブロックは、VPN・ラグ軽減ツールの共用中継アドレスを考慮してアカウント・端末単位と合わせて判断。
インフラチームの対応 海外の利用者が多ければ近くに接続拠点を自前で置く、「ラグ軽減ツールを使ったら良くなった」という報告が集中する通信事業者は経路を点検。
外部の対応 ユーザーに、VPN・ラグ軽減ツールをオフにして比較してみるよう案内。
数値の目安 近い中継サーバーなら数ms、別の国を回ると数十〜100ms以上が加わります。
グラフでは 一部だけ高い · RTT(ユーザー別)、接続元IPの事業者
確認箇所 接続元IPのASNがVPN・ラグ軽減ツール・ホスティング事業者かを確認し、ユーザーにVPN・ラグ軽減ツールをオフにしてPingとtracerouteを比較してもらう 該当する場合 VPN・ラグ軽減ツールを使ったときだけRTT・パケットロスが増えるか接続がブロックされ、tracerouteに中継サーバーを経由する区間が見える 該当しない場合 オンでもオフでも同じなら回線・通信事業者の区間。オンにした方が良くなるなら、元の通信事業者の経路(「迂回ルーティング」「ピーク時間帯のピアリング混雑」)の問題 確認手段 ユーザー側の環境で確認
もっと詳しく 逆に、通信事業者の経路が悪いときは、ラグ軽減ツールがより良い経路を通ってPingが下がることもあります。「ラグ軽減ツールを使ったら良くなった」という報告は、迂回ルーティングや夜の混雑といった通信事業者の経路の問題の手がかりです。
出典3件
L5 データセンターのネットワーク機器
原因11件 · メインページの章
ID dc-firewall · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ファイアウォールは、通過させたすべての接続をセッションテーブルに記録して追跡します。テーブルがいっぱいになると、新しい接続を受け付けられなくなります。
なぜ 接続の殺到や攻撃でセッション数が上限に到達 → すると 新しい接続を記録する空きエントリがなく拒否 → 画面では 新たに入ろうとする人は接続不可・無限ロード、一部の既存の接続も切断
症状 接続不可・無限ロード , 切断
要因 パケットロス
誰に起きるか サーバー全体
いつ 接続直後・メンテ明け, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:ログイン待機列システムで一斉に押し寄せる接続を調整、短い接続を繰り返さないよう接続を再利用、ハートビートが途切れた接続は先に整理(切れた接続がセッションテーブルを長く占有しないように)。クライアント:最も短いアイドルタイムアウトの半分以下の間隔でハートビートを送る、切れたら自動で再接続し、再試行間隔を延ばしながらランダムに分散(一斉に再び殺到しないように)。
インフラチームの対応 セッションテーブルのサイズを増やす、短時間で終わった接続を早く整理(終了したセッションのタイムアウトを短縮)、アイドルセッションのタイムアウトを短くするときはその値をゲーム開発チームに伝えてハートビート間隔を合わせる、攻撃の遮断、セッション数の使用率にアラート。
グラフでは 上限で頭打ち · ファイアウォールのセッション数、新規接続の失敗数
確認箇所 ファイアウォール機器の同時セッション数をセッション上限と一緒にグラフで確認し、機器のログでセッションを作れずに破棄した記録を探す。Linuxのファイアウォールならnf_conntrack_countをnf_conntrack_maxと比較してdmesgの「nf_conntrack: table full, dropping packet」を、AWSのインスタンスならethtool -Sのconntrack_allowance_exceededを確認 該当する場合 セッション数が上限で平らになった時刻から新規接続の失敗が増え、セッション作成失敗の記録や破棄カウンターも一緒に増える 該当しない場合 セッション数が上限にほど遠いのに接続できなければ「接続待ちキュー(backlog)のあふれ」かログインサーバー側。アイドル接続だけが切れるなら「クラウドのセキュリティグループによる接続追跡の期限切れ」 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
DDoS対策の経由・誤検知 DDoS scrubbing latency, false positives
ID dc-ddos · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
攻撃を防ぐためにトラフィックをスクラビングセンターに回すと経路が長くなり、正常なユーザーを攻撃と誤認してブロックすることもあります。
なぜ 攻撃の検知後(または常時)、入ってくるトラフィックをスクラビングセンターに迂回 → すると 経路が長くなり、一部の正常なパケットを攻撃と判定 → 画面では 全体のPingが上昇、特定の地域・通信事業者だけ接続不可
症状 入力遅延 , 接続不可・無限ロード , ワープ
要因 遅延, パケットロス
誰に起きるか サーバー全体, 特定の地域・ISP
いつ 人が集中したとき, ときどきランダムに
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ゲームのトラフィックパターン(ポート、パケットサイズ、毎秒のパケット数)をまとめてインフラチームに共有、UDPパケットは1,200バイト以下に保つ。
インフラチームの対応 ゲームのトラフィックパターンに合わせた防御ルール、地域ごとのスクラビング拠点、トンネル区間でTCPのパケットサイズを小さくする(MSSの調整)、地域・通信事業者別の接続失敗率で誤検知を確認。
数値の目安 スクラビング拠点が同じ国にあれば数ms、別の国の拠点を経由すると30〜100ms以上が加わります。通常は入ってくる方向だけが迂回し、サーバーの応答は直接出ていきます。フィルタリング済みのトラフィックをトンネルで戻して受け取る場合は、一度に送れるサイズ(MTU)も小さくなり、大きなパケットだけが消える問題につながることもあります。
グラフでは ある時点から階段状に上昇 · RTT(Ping)、地域・通信事業者別の接続失敗率
確認箇所 防御機器・サービスの迂回(スクラビング)の開始・終了記録と遮断ログを、RTTのグラフや地域・通信事業者別の接続失敗率と同じ時間軸に並べて確認。問題の地域からmtr・tracerouteで、経路にスクラビング拠点が入っていないか確認 該当する場合 迂回がオンになった時刻にRTTが一段上がってとどまり、オフになると戻る。または遮断ログに正常なユーザーのアドレスがあり、その地域・通信事業者だけ接続失敗率が上がる 該当しない場合 迂回・遮断の記録がない時刻にRTTが上がるなら「迂回ルーティング」か「BGPの経路変更・収束」。大きなパケットだけが消えるなら「MTUの不一致(大きなパケットだけ消える)」 確認手段 インフラのツールで確認(ゲームコード不要)
出典2件
ID dc-lb-idle · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
ロードバランサーは、アイドル状態の接続を一定時間後に削除します。ゲーム側は接続が維持されているものとみなしているうちに、切断されてしまいます。
なぜ プレイヤーがしばらくパケットを何も送らない(会話ウィンドウ、離席) → すると ロードバランサーがアイドル接続を整理(よくあるデフォルト値は60〜350秒) → 画面では 再び動いた瞬間に切断
症状 切断
要因 パケットロス
誰に起きるか 自分だけ, サーバー全体
いつ しばらく放置した後
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:最も短いアイドルタイムアウトの半分以下の間隔でハートビートを送る(60秒のALBの後ろなら30秒以下)、切れたら自動で再接続。サーバー:ハートビートに応答し、一定時間受け取れなければ先に接続を整理、セッショントークンで引き継ぐ。
インフラチームの対応 経路上にあるロードバランサーのアイドルタイムアウトの値を確認してゲーム開発チームに共有し、必要なら延ばす。
数値の目安 AWS ALBは60秒、NLBはTCP 350秒・UDP 120秒、Azure Load BalancerはTCP 4分がデフォルト値です。ALBとNLBのTCPの値は変更できますが、NLBのUDP 120秒は変更できません。ALBは時間が来るとサーバー側の接続も閉じますが、NLBは黙って削除するため、サーバーが気づかないまま接続が残りやすくなります。
グラフでは 接続が一斉に切れる · 切断数、切断前のアイドル時間
確認箇所 経路上にあるロードバランサーのアイドルタイムアウトの設定値を確認し、切れた接続ごとに最後のパケットから切断までにかかった時間を集計。AWS NLBならCloudWatchのTCP_ELB_Reset_Count(ロードバランサーが送ったRSTの数)も確認 該当する場合 切れた接続のアイドル時間が設定値(ALB 60秒、NLB TCP 350秒など)の直後に集中し、その時間より長く放置してから動くと再現する。NLBではその時刻にTCP_ELB_Reset_Countが増える 該当しない場合 アイドル時間と関係なく切れるならこの原因ではない。ロードバランサーを通さずに直接つなぐサーバーで350秒付近に集中するなら「クラウドのセキュリティグループによる接続追跡の期限切れ」、ユーザーの家庭用ルーター側なら「NATマッピングの期限切れ」 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID dc-cloud-conntrack · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
クラウドのサーバーに付いているファイアウォール(セキュリティグループ)も接続を追跡し、アイドル接続の追跡エントリは決められた時間の後に期限切れになります。ロードバランサーを通さずに直接つなぐサーバーでも、しばらく放置していたプレイヤーが切断されることがあります。
なぜ セキュリティグループがゲームの接続を追跡する設定(特定のアドレスだけ許可、アウトバウンドルールの制限、NLB経由など) → すると しばらくアイドル状態だった接続の追跡エントリが期限切れになり、その後に届いたパケットをセキュリティグループが黙って破棄 → 画面では 離席後に再び動くと反応がないまま切断。サーバープログラムはしばらく気づかない
症状 切断
要因 パケットロス
誰に起きるか 自分だけ, サーバー全体
いつ しばらく放置した後
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:最も短いアイドルタイムアウトの半分以下の間隔でハートビートを送る(TCP 350秒なら175秒以下、UDPストリーム180秒なら90秒以下)、切れたら自動で再接続。サーバー:ハートビートに応答し、一定時間受け取れなければ先に接続を整理、セッショントークンで引き継ぐ。
インフラチームの対応 インスタンスの接続追跡時間(TcpEstablishedTimeout)を確認し必要なら延ばす(UDPは180秒が最大のため延ばせない)、追跡が発生しないセキュリティグループ構成を検討(ゲームのポートはすべてのアドレスを許可、アウトバウンドルールはすべて許可。NLBを経由する接続はそれでも追跡される)、新世代のインスタンスに移行するときにアイドル試験。
数値の目安 AWSでは、Nitro v6のインスタンスタイプはアイドル状態のTCP接続の追跡エントリをデフォルトで350秒後に削除します(それ以外のタイプは5日)。UDPは、要求と応答が何度もやり取りされたフロー(ストリーム)が180秒、一方向だけに流れたか要求・応答が1回だけのフローが30秒がデフォルトです。
グラフでは 接続が一斉に切れる · 切断数、切断前のアイドル時間
確認箇所 インスタンスの接続追跡時間の設定とセキュリティグループのルール(追跡が発生する構成か)を確認し、切れた接続のアイドル時間を集計。切れた直後にサーバーでss -tnoiを実行し、その接続がESTABLISHEDのまま残って再送タイマー(timer:(on,…))が動き、backoffが増えていくかを確認 該当する場合 切れた接続のアイドル時間がTCP 350秒、UDPストリーム180秒、UDP一方向30秒の直後に集中し、サーバー側のソケットは切断を検知できないままESTABLISHEDで残る(サーバーに送るデータがあれば再送だけを繰り返す) 該当しない場合 セキュリティグループが追跡しない構成(ゲームのポートをすべてのアドレスに許可、アウトバウンドルールはすべて許可、NLBを経由しない)ならこの原因ではない。NLBを経由するなら「ロードバランサーのアイドルタイムアウト」と値を比較 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID dc-nat-gateway · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
プライベートサブネットのサーバーから外部(プラットフォーム認証・決済・外部API)への接続は、NATゲートウェイがアドレスとポートを変換して送り出します。同じ宛先への同時接続がゲートウェイのポート上限を超えると、新しい接続が失敗します。
なぜ サーバー群が、プラットフォーム認証・決済のような同じ外部アドレスへ短い接続を大量に開くか、接続を長く開いたままにする → すると NATゲートウェイがその宛先に使う送信元ポートをこれ以上割り当てられず、新しい接続が失敗 → 画面では ゲーム内は問題ないのに、ログイン・決済・報酬付与のように外部を呼び出す機能だけが失敗するか遅れる(接続不可・無限ロード、不発・ロールバック)
症状 接続不可・無限ロード , 不発・ロールバック
要因 パケットロス, 遅延
誰に起きるか 特定の機能だけ, サーバー全体
いつ 接続直後・メンテ明け, 夜のピーク時間帯, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 外部APIは接続を再利用し(HTTP keep-alive、コネクションプール)、リクエストごとに新しい接続を開かない、プールに残したアイドル接続はNATのアイドルタイムアウト(AWSは350秒)より短い間隔でkeepaliveを送るか先に閉じる、失敗したら再試行間隔を延ばしながらランダムに分散、外部呼び出しごとの失敗率・遅延を記録。
インフラチームの対応 NATゲートウェイにIPアドレスを追加(AWSのパブリックNATゲートウェイにはElastic IPをデフォルトで2つまでしか付けられないため、それ以上はクォータの引き上げを申請)、アベイラビリティーゾーン・サブネットごとにゲートウェイを分ける、ポート割り当て失敗のメトリクス(AWSのErrorPortAllocation、AzureのSNAT Connection CountのFailed、Google Cloudのdropped_sent_packets_countのOUT_OF_RESOURCES)にアラート、Google Cloud NATはVMあたりの最小ポート数を増やすか動的ポート割り当てを使う。
数値の目安 AWS NATゲートウェイは、IPアドレス1つで同じ宛先(IP・ポート・プロトコル)に同時接続を55,000まで開くことができ、IPを8つまで付けて増やせます。350秒間通信のない接続は削除し、その後この接続に送られたパケットにはRSTを返します。Azure NAT Gatewayは、パブリックIP 1つあたりSNATポート64,512個(IPは最大16個)です。Google Cloud NATはNAT IP 1つあたり64,512ポートをVMごとに分けて割り当てますが、VMあたりの最小ポート数のデフォルトが64(静的割り当て)のため、デフォルト設定では1台のVMが同じ宛先に同時に開ける接続は、たいてい64に制限されます。
グラフでは 上限で頭打ち · NATゲートウェイの同時接続数、ポート割り当ての失敗数
確認箇所 AWSはCloudWatchのNATゲートウェイのメトリクスErrorPortAllocation・ActiveConnectionCount・PacketsDropCount(AzureはSNAT Connection CountをFailed状態で絞り込んだ値とDropped Packets、Google Cloudはdropped_sent_packets_countのreason OUT_OF_RESOURCES)を、ゲームサーバーの外部呼び出しが失敗した時刻と並べて確認 該当する場合 外部呼び出しが失敗した時刻にErrorPortAllocation(AzureはFailed状態のSNAT Connection Count、Google CloudはOUT_OF_RESOURCESによる破棄)が0より大きくなり、失敗が認証・決済サーバーのように接続が多く集中する1〜2か所の宛先への呼び出しに集まる 該当しない場合 ポート割り当ての失敗が0なのに、ゲームサーバーのconnectがEADDRNOTAVAILで失敗し、TIME_WAITがエフェメラルポートの範囲に迫っていれば「サーバー間接続のエフェメラルポート枯渇」。接続はできるのに応答だけが遅ければ「外部サービスへの依存」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく サーバー1台のエフェメラルポートが尽きる「サーバー間接続のエフェメラルポート枯渇」とは異なり、この上限はNATゲートウェイにかかり、ゲートウェイの後ろのサーバー群が共有します(Google Cloud NATはVMごとに分けて割り当て)。サーバー側のTIME_WAITとエフェメラルポートの範囲には余裕があるのに外部呼び出しだけが失敗するなら、こちらです。閉じた接続のポートもすぐには同じ宛先に再利用されないため(Azureはクールダウン、Google CloudはTIME_WAITの間は使用不可)、短い接続を繰り返すほど早く上限に達します。
出典7件
ID dc-lb-imbalance · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
接続が1台のサーバーだけに集中したり、すでに落ちたサーバーに人を送り続けたりします。
なぜ 振り分けルールが合っていないか、ヘルスチェックが実際の状態を捉えられていない → すると 1台のサーバーだけが過負荷、または落ちたサーバーへの接続試行 → 画面では 一部のチャンネル・一部の人だけスローモーション、接続不可・無限ロード
症状 スローモーション , 接続不可・無限ロード
要因 ストール, パケットロス
誰に起きるか 特定の場所・チャンネル
いつ 接続直後・メンテ明け, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ロードバランサーからの確認リクエストに、実際のゲームの状態(ティックの進行、DB接続)を見て応答するヘルスチェックの実装、サーバーの負荷の値も一緒に返す。
インフラチームの対応 ヘルスチェックを実際のゲームの応答を確認する方式に変える、サーバー負荷に基づく振り分け、サーバーごとの接続数の差を監視。
グラフでは 一部だけ高い · サーバーごとの接続数・CPU使用率
確認箇所 ロードバランサー配下のサーバーごとの接続数(ss -s)とCPU使用率を1つのグラフに重ねて確認し、ロードバランサーのターゲットのヘルス状態(AWSはCloudWatchのHealthyHostCount・UnHealthyHostCount)をゲームサーバーの実際の状態と比較 該当する場合 1〜2台のサーバーだけ接続数・CPUがほかのサーバーより大きく高いか、ティックが止まったサーバーがヘルス状態「正常」のまま新しい接続を受け続けている 該当しない場合 サーバーごとの接続数が均等なのに1つのチャンネルだけ重ければ、そのチャンネル内の負荷(「シングルスレッドのエリア過負荷(ホットスポット)」) 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 AWS 2025: AWS us-east-1のDynamoDB DNS障害と長引いた復旧
出典3件
ID dc-microburst · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ, インフラチーム・サーバーインフラ
複数のサーバーが同じ瞬間に数千人へ一斉にパケットを送ると、そのトラフィックが集まるスイッチポートの小さなバッファが1ms足らずであふれます。
なぜ ワールドボスの出現・大規模スキル、または複数サーバーのティックが同じ瞬間に重なって一斉に送信 → すると 複数のポートが1つのポートに集まる場所や、速いポートから遅いポートへ渡る場所のバッファ(ポートあたり数百KB〜数MB)が瞬間的にいっぱいになる → 画面では 一部のパケットが破棄され、多くの人が同時にワープ・スキル不発
症状 ワープ , 不発・ロールバック
要因 パケットロス
誰に起きるか 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ, インフラチーム・サーバーインフラ
ゲーム開発チームの対応 送信をティック内で均等に分ける(ペーシング)、サーバーごとにティックの開始タイミングを少しずつずらす。
インフラチームの対応 ネットワーク:バッファの大きなスイッチ、トラフィックの分散(サーバーを複数のスイッチ・ポートに分けて配置)、スイッチポートごとの破棄カウンターを監視。サーバー機器・OS:サーバー全体の送信速度の上限(Linuxのtcシェーパー)。
数値の目安 10Gbpsのポートが1msで送り出せる量は約1.25MBです。2つのポートのトラフィックが1つのポートに同時に集まると、1msごとに1.25MBずつたまります。1秒平均の使用率が10%でも、1ms単位ではあふれることがあります。
グラフでは 人数・負荷に連動して上昇 · スイッチポートの出力破棄数
確認箇所 サーバーがつながるスイッチポートと、そのトラフィックが集まるポートの出力破棄カウンター(ifOutDiscards、機器によってはoutput drops)をできるだけ短い間隔で集め、ボスの出現・大規模戦闘の時刻と照合。1秒・1分平均の使用率グラフだけでは見えない 該当する場合 平均使用率は低いのに、人が1か所に集まる瞬間ごとに出力破棄が増え、そのときに複数のユーザーが同時にワープ・スキル不発を報告する 該当しない場合 平均使用率が高い時間帯に破棄が継続的に増えるなら「データセンター回線の飽和」。入力エラー(CRC)が増えるなら「ケーブル不良・ポートエラー」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID dc-uplink · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
アップデートデータの配信・ログ転送・バックアップがゲームと同じ回線を使うと、回線がいっぱいになります。
なぜ 大容量の転送が同じ回線を占有 → すると 回線のキューとパケットロスが増加 → 画面では サーバー全体でPingの上昇とワープ
症状 入力遅延 , ワープ
要因 遅延, パケットロス
誰に起きるか サーバー全体
いつ 一定の周期で, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
インフラチームの対応 ネットワーク:ゲームのトラフィックを優先処理(QoS)、大容量転送用の回線を分離、回線使用率のアラート。サーバー機器・OS:バックアップ・ログ転送・デプロイに速度制限をかけ、空いている時間帯に実行。
グラフでは 上限で頭打ち · 回線使用率、RTT(Ping)
確認箇所 データセンター回線(アップリンク)のインターフェースの使用率(SNMPのifHCInOctets・ifHCOutOctetsから計算)と出力破棄(ifOutDiscards)を、バックアップ・デプロイ・ログ転送のスケジュールと同じ時間軸に並べて確認 該当する場合 回線使用率が帯域幅の上限に張り付いて平らになった時刻に、サーバー全体のRTTと破棄が上がり、その時刻が大容量の転送作業と重なる 該当しない場合 分単位の使用率が上限にほど遠いのに破棄があるなら「スイッチのマイクロバースト」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID dc-failover · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ルーター・ファイアウォールの1台が故障して予備機に切り替わる(フェイルオーバー)数秒の間、全員が止まります。
なぜ 機器の故障またはメンテナンスで予備機に切り替え → すると 切り替えに数秒、セッション情報が同期されていなければ接続がリセットされる → 画面では サーバーの全ユーザーが同時にフリーズ、大量の切断
症状 フリーズ , 切断
要因 パケットロス
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:短い途切れ(数秒)に耐えるタイムアウト、切れても再接続すればセッショントークンでセッションを引き継げるようにする。クライアント:切れたら自動で再接続(一斉に殺到しないよう再試行間隔をランダムに分散)。
インフラチームの対応 接続状態を共有する冗長化、BFDで故障を1秒以内に検知、切り替え試験を定期的に実施。
数値の目安 機器が故障をすぐに検知すれば1〜3秒前後です。高速な故障検知(BFD)なしでBGPのデフォルトのタイマーだけに任せると、隣接する機器が検知するまでの90〜180秒間、経路が途切れることがあります。
グラフでは 接続が一斉に切れる · 接続数、サーバー全体の送受信量
確認箇所 ルーター・ファイアウォールのイベントログ(VRRPの役割変更、BFD・BGPセッションのダウン、フェイルオーバーの記録)と、同じ時刻のサーバー全体の接続数・送受信量を確認 該当する場合 機器ログの切り替え時刻に、その機器の配下にあるすべてのサーバーのトラフィックが数秒間0になるか、接続数が同時に落ちる 該当しない場合 1台のサーバーの接続だけが落ちるなら「サーバークラッシュ」か「NICドライバー・ファームウェアの問題」。機器ログがきれいで、止まったサーバーがクラウドの仮想マシン1台なら「クラウドホストのメンテナンス・ライブマイグレーション」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ケーブル不良・ポートエラー Bad cable / optics (CRC errors)
ID dc-bad-cable · 主担当 インフラチーム・ネットワークインフラ
光モジュールやケーブルが不良だと、その経路を通るパケットが一定の割合で壊れます。
なぜ 光モジュール・ケーブルの不良でビットエラー → すると 壊れたパケットは機器が黙って破棄 → 画面では その経路を使う一部のサーバー・ユーザーだけが、継続的なパケットロスでワープ・引き戻し
症状 ワープ , 引き戻し
要因 パケットロス
誰に起きるか 特定の場所・チャンネル
いつ 常に
担当 主担当 インフラチーム・ネットワークインフラ
インフラチームの対応 ポートエラー(CRC)カウンターの監視・アラート、光モジュール・ケーブルなどの部品交換、交換までは問題のリンクを外して迂回。
グラフでは 一部だけ高い · ポートごとのCRCエラー数、サーバー・経路ごとのパケットロス率
確認箇所 リンクの両端のCRCカウンターを確認。スイッチはポートのFCSエラー(dot3StatsFCSErrors)・入力エラー(ifInErrors)、サーバーはip -s -s linkのRX errorsのうちcrc(カーネル統計のrx_crc_errors) 該当する場合 1つのポートのCRCエラーがトラフィック量・時間帯と関係なく継続的に増え、そのポートを通るサーバー・ユーザーだけにパケットロスがある 該当しない場合 CRCエラーがなく出力破棄だけが増えるなら混雑(「スイッチのマイクロバースト」「データセンター回線の飽和」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID dc-mtu · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
途中の区間のMTU(一度に送れるサイズ)が小さくなっているのにサイズ超過の通知がブロックされると、大きなパケットだけが消え続けます。
なぜ トンネル・VPNの区間でMTUが小さくなる → すると サイズ超過の通知(ICMP)がファイアウォールでブロックされ、送信側が気づかない → 画面では インベントリ・キャラクター一覧のような大きな画面を開いたときだけフリーズした後に切断
症状 フリーズ , 切断 , 接続不可・無限ロード
要因 パケットロス
誰に起きるか 特定の地域・ISP, 自分だけ
いつ 特定の操作をしたとき, 接続直後・メンテ明け
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 サーバー側で直接下げるなら、ソケットの最大セグメントサイズ(TCP_MAXSEG)を設定(ゲームのコードでメッセージを細かく分けるだけでは防げない)、UDPパケットは1,200バイト以下に保つ。
インフラチームの対応 ネットワーク:トンネル区間でTCPのパケットサイズを小さくする(MSSの調整)、ファイアウォール・クラウドのネットワークACLでサイズ超過の通知(ICMP)を許可。サーバー機器・OS:サーバーのファイアウォール・クラウドのセキュリティグループでもサイズ超過の通知(ICMP)を許可、サーバーカーネルのMTU探索(tcp_mtu_probing=1)を有効化(数秒止まった後にようやく働く最後のセーフティネット)。
数値の目安 通常は1,500バイトで、トンネルを通ると1,400前後に小さくなります。
グラフでは 一部だけ高い · 地域・通信事業者別の切断、大きな応答の失敗
確認箇所 問題のユーザーのPCからサーバーへ、フラグメント禁止の印(DF)を付けたpingをサイズを変えながら送る。Windowsはping /f /l 1472 SERVER_IP、Linuxはping -M do -s 1472 SERVER_IP(1,472はMTU 1,500からIPヘッダー20バイトとICMPヘッダー8バイトを引いた値)。サイズを小さくしながら通る最大サイズを探し、サーバー側のセキュリティグループ・ファイアウォールがICMPのサイズ超過通知(Fragmentation Needed)を許可しているか確認 該当する場合 小さいpingは通るのに1,472バイトのDF付きpingは失敗し(応答なし、またはフラグメント化が必要というエラー)、通る最大サイズが1,400前後と小さい。同じ地域のユーザーが大きな画面を開いたときだけフリーズする 該当しない場合 1,472バイトのDF付きpingも問題なく通るなら経路MTUの問題ではない。小さいpingも通らないならICMP自体がブロックされているため、この方法では判断できない 確認手段 ユーザー側の環境で確認
出典5件
L6 サーバーのネットワークカード
原因9件 · メインページの章
ID nic-irq · 主担当 インフラチーム・サーバーインフラ
NICがパケット到着の割り込みを1つのCPUコアにだけ送ると、そのコアがボトルネックになります。
なぜ 受信キューが1つだけか、複数のコアに分散するRSSが無効 → すると 1つのコアが100%になり、パケットを時間内に取り出せない → 画面では 人が集中したときにサーバー全体でパケットロスと遅延(ワープ・入力遅延)
症状 ワープ , 引き戻し , 入力遅延
要因 パケットロス, 遅延
誰に起きるか サーバー全体
いつ 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 RSS(NICが分散)・RPS(カーネルが分散)の設定、割り込みを複数のコアに分散、UDPはポートまで見てキューを分けるよう設定(ethtool -Nのrx-flow-hash udp4 sdfn)、割り込み処理のコアとゲームのティックスレッドのコアを分離、コアごとの%softを監視。
数値の目安 1つのコアがカーネル経由で処理できる量は、パケットサイズと設定によっておおよそ毎秒数十万パケットです。コアごとの使用率で、受信処理の割合(mpstatの%soft)が1つのコアにだけ偏っていればこのケースです。
グラフでは 上限で頭打ち · コアごとの%soft、毎秒の受信パケット数
確認箇所 mpstat -P ALL 1でコアごとの%soft(ソフトウェア割り込み処理の割合)を確認し、/proc/interruptsでNICのキューごとの割り込みがどのコアに行っているか、ethtool -lでキュー数、ethtool -Sでキューごとのパケット数(名前はドライバーごとに異なる)を確認 該当する場合 1つのコアだけ%softが100%近くに張り付き、残りは空いていて、割り込みとパケットが1つのキューに集中。そこから毎秒の受信パケット数がそれ以上上がらない 該当しない場合 %softが複数のコアに均等に分散していればこの原因ではない。CPUは空いているのにパケットロスがあれば「クラウドのPPS上限超過」か「リングバッファ不足」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく キューが複数あっても、ゲートウェイ・プロキシのように少数のアドレスからトラフィックの大半が来ると、1つのキューに集中します。UDPはNICのデフォルト設定がアドレスだけを見てキューを分けることがあり、ポートまで見るように変えないと均等に分散しません。
出典4件
リングバッファ不足 RX ring buffer overflow
ID nic-ring · 主担当 インフラチーム・サーバーインフラ
NICがパケットを一時的に入れておくリングバッファが小さいと、瞬間的に集中したときにバッファがあふれて破棄されます。
なぜ リングバッファがデフォルト値(ドライバーごとにスロット256〜2,048個)のままで小さい → すると バースト時にCPUが取り出す前にバッファがあふれる → 画面では バーストの瞬間だけパケットロス(ワープ・スキル不発)。ゲームサーバーのログには痕跡がない
症状 ワープ , 不発・ロールバック
要因 パケットロス
誰に起きるか サーバー全体
いつ 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 リングバッファを大きくする(ethtool -G)、破棄(drop)カウンターを監視(ethtool -Sのrx_missed_errorsなど、名前はドライバーごとに異なる)。
数値の目安 毎秒100万パケットが集中すると、スロット1,024個は約1msで埋まります。その間にCPUが一度でも遅れればあふれます。ほとんどのNICは数千個まで増やせます。
グラフでは 不定期なスパイク · NICの受信破棄カウンター
確認箇所 ethtool -Sの受信破棄カウンター(rx_missed_errors、rx_fifo_errorsなど、名前はドライバーごとに異なる)とip -s -s linkのmissedを短い間隔で集め、ethtool -gで現在のリングサイズと最大値を確認 該当する場合 バーストの瞬間に破棄カウンターが増え、現在のリングサイズが最大値よりずっと小さい。リングを大きくすると破棄が減る 該当しない場合 破棄カウンターが変わらないのにパケットロスがあれば、カーネルの次の段階(「カーネルのソケットバッファ不足」)かネットワーク区間。1つのコアの%softが100%なら「NIC割り込みの単一コア集中」 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID nic-coalesce · 主担当 インフラチーム・サーバーインフラ
CPUの負担を減らすために、パケットをまとめてから一度に知らせると、まとめる時間の分だけ遅れます。
なぜ NICが一定の時間・個数だけまとめてから通知 → すると まとめている間、パケットが待たされる → 画面では わずかな遅延の増加。通常は小さいが、過剰だとms単位
症状 入力遅延
要因 遅延
誰に起きるか サーバー全体
いつ 常に
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 適応型コアレッシング、ゲームサーバーに合った値に調整(ethtool -C)。
数値の目安 通常は数十〜数百µsです。ゲームではたいてい無視できる程度ですが、設定が過剰だとms単位まで大きくなります。
グラフでは 最初から常に高い · 同じデータセンター内の往復時間
確認箇所 ethtool -cで現在のコアレッシング設定(adaptive-rx、rx-usecs、rx-frames)を確認し、同じデータセンターのほかのサーバーとのpingの往復時間を、設定を変える前後で比較 該当する場合 rx-usecsが数百µs以上と大きく設定されていて、値を小さくすると同じデータセンター内の往復時間がその分だけ短くなる 該当しない場合 小さくしても往復時間が変わらなければこの原因ではない 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
クラウドのPPS上限超過 Cloud PPS / bandwidth allowance
ID nic-cloud-pps · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
クラウドのサーバーには種類ごとに毎秒のパケット数・帯域幅の上限があり、超えると黙って破棄されます。
なぜ 同時接続数が増えて、毎秒のパケット数がインスタンスの上限を超える → すると クラウドのネットワークが超過分を破棄 → 画面では 原因のわからないパケットロスでワープ・スキル不発。サーバーのCPUには余裕がある
症状 ワープ , 不発・ロールバック
要因 パケットロス
誰に起きるか サーバー全体
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
ゲーム開発チームの対応 パケットをまとめる(1ティックのメッセージを1つのパケットに)、ごく小さなパケットを頻繁に送らない。
インフラチームの対応 上限超過カウンターの確認(AWSはpps_allowance_exceeded、conntrack_allowance_exceededなど)・アラート、より大きなインスタンス、接続追跡の上限は追跡が発生しないセキュリティグループ構成で回避。
外部の対応 クラウド事業者に、インスタンスの種類ごとの毎秒パケット数・接続追跡の上限を問い合わせ。
数値の目安 上限はインスタンスのサイズごとに異なり、毎秒のパケット数の上限は公開されていないことが多いです。小さいインスタンスの「最大10Gbps」は、クレジットが残っている間(通常5〜60分)だけ使えるバースト速度で、普段のベースライン速度はずっと低くなります。
グラフでは 上限で頭打ち · 毎秒のパケット数、allowance超過カウンター
確認箇所 ethtool -SのENAカウンターpps_allowance_exceeded・bw_in_allowance_exceeded・bw_out_allowance_exceeded・conntrack_allowance_exceededを短い間隔で集め、毎秒のパケット数と一緒に確認。CloudWatchエージェントでこれらのカウンターを送信し、アラートを設定することもできる 該当する場合 パケットロスが出た時刻にallowance超過カウンターが増え、毎秒のパケット数が一定の値から上がらない。サーバーのCPUには余裕がある 該当しない場合 超過カウンターが変わらなければこの原因ではない。1つのコアの%softが100%なら「NIC割り込みの単一コア集中」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく conntrack_allowance_exceededは、接続追跡テーブルがいっぱいになって新しい接続を破棄したケースです。テーブルには余裕があるのに、アイドル接続だけが追跡の期限切れで切れる場合は「クラウドのセキュリティグループによる接続追跡の期限切れ」の項目を参照してください。
出典2件
NIC帯域幅の飽和 NIC bandwidth saturation
ID nic-saturate · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
1Gbps・10Gbpsのカードを限界まで使うと、送信キューが長くなり、最終的に破棄されます。
なぜ ブロードキャストの増加で送信量がカードの限界に到達 → すると 送信キューが長くなり、あふれると破棄 → 画面では サーバー全体で遅延・パケットロス(入力遅延・ワープ)
症状 入力遅延 , ワープ
要因 遅延, パケットロス
誰に起きるか サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 送信量を減らす(関心領域、圧縮、差分のみ送信)。
インフラチームの対応 カードの増強(より高速なNIC、クラウドならより大きなインスタンス)、NIC使用率のアラート。
グラフでは 上限で頭打ち · NICの送信量、送信破棄
確認箇所 sar -n DEV 1のtxkB/sと%ifutil(インターフェース速度に対する使用率)をNICの速度・インスタンスの帯域幅と比較し、ip -s linkのTX droppedも一緒に確認 該当する場合 送信量がNIC・インスタンスの帯域幅付近で平らになり、そこから送信破棄とサーバー全体の遅延が増える 該当しない場合 帯域幅に余裕があればこの原因ではない。小さなパケットが多くてパケットロスがあれば「クラウドのPPS上限超過」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID nic-noisy · 主担当 インフラチーム・サーバーインフラ · 副担当 外部・外部
同じ物理サーバー上のほかの仮想マシンがネットワーク・CPUを大量に使うと、自分のサーバーの処理が不規則に遅れます。
なぜ 同じ物理サーバー上のほかの仮想マシンがリソースを大量に使用 → すると 自分の仮想マシンのパケット処理が不規則に遅れる → 画面では はっきりした原因がないのに、ときどきジッター(到着間隔のばらつき)が生じてカクつき
症状 カクつき
要因 ジッター
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ · 副担当 外部・外部
インフラチームの対応 専有ホスト、性能が保証されたインスタンス、ジッターが続くインスタンスは停止してから再起動し、別のホストに移す。
外部の対応 クラウド事業者に問題のあるホストを報告。
グラフでは 不定期なスパイク · 同じデータセンター内の往復時間のジッター、%steal
確認箇所 同じデータセンターのほかのサーバーへpingを送り続けて往復時間のジッターを記録し、mpstatの%stealと合わせて、同じ構成のほかのインスタンスと比較 該当する場合 このインスタンスだけ往復時間のジッターや%stealが不規則に跳ね、同じ構成のほかのインスタンスは落ち着いている。停止してから再起動し、別のホストに移すと消える 該当しない場合 同じ構成のインスタンスがすべて同じように跳ねるならホストの問題ではない。ゲームサーバー側の負荷やネットワーク区間を確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典2件
ID nic-host-maintenance · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
クラウド事業者は物理サーバー(ホスト)をメンテナンスするとき、仮想マシンを別のホストに移したり(ライブマイグレーション)、一時的に止めたりします。その間はサーバー全体が止まり、止まる時間が長いと接続が切れます。
なぜ 事業者がホストのメンテナンスや故障予測のために、仮想マシンを別のホストに移すか一時停止 → すると 移している間はCPU・メモリ・ネットワークが遅くなり、最後に仮想マシンが一瞬完全に止まる(事業者と方式によって1秒未満〜30秒前後) → 画面では サーバーの全員が同時にフリーズした後に早送り・ワープ、停止がタイムアウトより長ければ大量の切断
症状 フリーズ , 早送り , ワープ , 切断
要因 ストール, パケットロス
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
ゲーム開発チームの対応 数秒の停止に耐えるタイムアウト、停止後に追いつくためのティック数に上限を設ける、経過時間はモノトニッククロック(monotonic clock)で計算、メンテナンス通知を受けたら進行状況を保存してユーザーを別のサーバーに移す手順。
インフラチームの対応 メンテナンス通知の購読とアラート(Google Cloudのmaintenance-event、AWSのスケジュールされたイベント・AWS Health、Azure Scheduled Events)、通知を受けたらユーザーの少ない時間帯に前もってサーバーを入れ替える、事業者が許可していればメンテナンス時刻を調整(Azure Maintenance Configuration、種類によってはAWSのスケジュールされたイベント)、メンテナンス記録と障害記録を照合。
外部の対応 クラウド事業者にメンテナンスのスケジュールと影響範囲を確認、同じインスタンスで停止が繰り返されるなら報告。
数値の目安 Google Compute Engineは、ライブマイグレーションによる停止は通常1秒よりずっと短いとしており、停止中にシステム時刻が最大5秒先に飛ぶことがあります。メタデータのmaintenance-eventの値は、移行の60秒前に変わります(それ以前にこの値を一度以上取得している場合)。Azureは、再起動が不要なメンテナンスであればほぼ常に10秒未満、まれに(一般的なサイズでは18か月に1回以下)約30秒止まり、ライブマイグレーションは通常5秒を超えません。Azure Scheduled Eventsは、こうした停止(Freeze)を少なくとも15分前に通知します。ただし、ホストのハードウェアが突然故障した場合は、通知なしですぐに復旧を始めます。
グラフでは 途切れた後にまとめて到着 · サーバーの送受信パケット数、ティック間隔
確認箇所 停止した時刻を事業者の記録と照合。Google Cloudは監査ログのcompute.instances.migrateOnHostMaintenance、AWSはdescribe-instance-status・AWS Healthのスケジュールされたイベント、Azureはアクティビティログ(Activity Log)のMicrosoft.Compute/virtualMachines/liveMigration/actionと、VMの可用性メトリクス(VmAvailabilityMetric)が0に落ちた時刻。サーバー内では、停止中にメトリクス・ログが空白になっていないか、直後に時刻が飛んでいないか(時刻同期のログ)を確認 該当する場合 サーバー全体が止まった時刻が、事業者の記録したメンテナンス・マイグレーションの時刻と重なり、その数秒間はサーバー内のメトリクス・ログがすべて空白 該当しない場合 事業者の記録になく、短い停止が頻繁に繰り返されるなら「CPUスチール(仮想マシン)」。カーネルログにNICのリセットの記録があれば「NICドライバー・ファームウェアの問題」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく AWSはスケジュールされたイベントで通知します。system-rebootは再起動して新しいホストに移すことを、system-maintenanceはネットワーク・電源のメンテナンスで一時的に影響を受ける可能性があることを意味します。停止が数秒でも、その間にサーバーへ送ったパケットのACKを受け取れなかったクライアントは再送の待ち時間を2倍ずつ延ばしていくため、停止が解けた後もTCP接続はさらに長く止まったままになることがあります(「TCPのRTOと指数バックオフ」)。停止から復帰すると時刻が飛んで「システム時刻のジャンプ(NTPステップ)」につながることもあり、ロードバランサーのヘルスチェックが失敗してそのサーバーが一時的に外されることもあります。移行できないインスタンス(Google Cloudのベアメタルインスタンスなど)は、メンテナンス時に停止または再起動されます。
出典6件
ID nic-reset · 主担当 インフラチーム・サーバーインフラ
ドライバーのバグや機能の誤動作でカードが止まり、再起動している間はすべての送受信が途切れます。
なぜ ドライバーのバグ、オフロード機能の誤動作 → すると NICが止まって再起動(数秒) → 画面では そのサーバーの全員が一緒にフリーズした後、ワープするか切断
症状 フリーズ , 切断
要因 パケットロス
誰に起きるか サーバー全体
いつ ときどきランダムに, 長時間稼働するほど
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 カーネルログの「transmit queue … timed out」「Link is Down」の記録を確認・アラート、ドライバー・ファームウェアの更新、問題のある機能(オフロードなど)を無効化。
グラフでは 途切れた後にまとめて到着 · サーバーの送受信パケット数
確認箇所 dmesgでカーネルログから「NETDEV WATCHDOG … transmit queue N timed out」、ドライバーのリセット、「Link is Down」「Link is Up」の記録を探し、その時刻のサーバーの送受信パケット数を確認 該当する場合 止まった時刻のカーネルログに送信キューのタイムアウトやリンクのダウン・アップの記録があり、その数秒間は送受信パケット数が0 該当しない場合 カーネルログがきれいで、スイッチ側のポートも正常なら、ゲームサーバープロセスの停止(「サーバーGCの全停止」「デッドロック」)か「ネットワーク機器のフェイルオーバー」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID nic-offload · 主担当 インフラチーム・サーバーインフラ
複数のパケットを1つにまとめてCPUの負担を減らす機能です。設定によっては、小さなゲームのパケットが、一緒にまとめる次のパケットを少し待つことがあります。
なぜ NIC・カーネルが到着したパケットをまとめて処理 → すると ハードウェアによる結合(LRO)や結合の待ち時間の設定が有効だと、次のパケットを待って少し待機 → 画面では わずかな遅延の増加(たいてい数十µs以下)
症状 入力遅延
要因 遅延
誰に起きるか サーバー全体
いつ 常に
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 ゲームのトラフィックに合わせて調整(LROを無効化、結合の待ち時間の設定を確認)、効果はたいてい小さいのでほかの原因より後に確認。
グラフでは 最初から常に高い · 同じデータセンター内の往復時間
確認箇所 ethtool -kでlro・groの状態を、デバイスのsysfs設定gro_flush_timeoutの値を確認し、変更の前後で同じデータセンター内の小さなパケットの往復時間を比較 該当する場合 LROが有効か、gro_flush_timeoutが0より大きく、無効にするか0にすると小さなパケットの往復時間が短くなる 該当しない場合 変えても差が数µs以内ならこの原因ではない 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
L7 サーバーOS(カーネル)
原因14件 · メインページの章
ID so-backlog · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
メンテ明けに数万人が同時に接続すると、カーネルの接続待ちキュー(backlog)があふれ、接続要求が破棄されます。
なぜ メンテ終了と同時に、ゲームサーバーがacceptで接続を処理する速度を上回る勢いで接続が殺到 → すると カーネルの接続待ちキュー(backlog。サーバーのコードがlistenに渡した値とカーネルの上限のうち小さいほう)が満杯 → 画面では 接続要求が破棄されて再試行が繰り返され、接続不可・無限ロード
症状 接続不可・無限ロード
要因 パケットロス
誰に起きるか サーバー全体
いつ 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:コードでlistenに渡す値を増やす、接続を受け付けるスレッドがほかの処理で止まらないようにする、ログイン待機列の仕組み。クライアント:再試行の間隔を広げる(ランダムに分散)。
インフラチームの対応 カーネルのsomaxconnを増やす(サーバーのコードのlistenの値と両方を上げないと効果がない)、SYN Cookieを有効にしておく、あふれた回数の監視(nstatのTcpExtListenOverflows)。
数値の目安 Linuxカーネルの上限(somaxconn)は5.4からデフォルト4,096(それ以前は128)ですが、サーバーのコードがlistenにそれより小さい値を渡すと、その値が上限になります。Linuxはキューが満杯になると、接続要求をエラーも返さずに黙って破棄します。クライアントのOSが1秒後から何度か再送するため、プレイヤーには「接続失敗」よりも長いロードに見えます。Windowsサーバーは拒否の応答を返すので、クライアントにはすぐに「接続失敗」と表示されます。
グラフでは 接続直後・メンテ明けに急増 · 接続待ちキューのあふれ数(ListenOverflows)、接続試行数
確認箇所 nstat -azでTcpExtListenOverflows・TcpExtListenDropsの増加量を確認し、ss -ltnでリッスンソケットのRecv-Q(acceptを待っている接続数)とSend-Q(backlogの上限)を比較 該当する場合 接続が殺到した時刻にListenOverflowsが増え、リッスンソケットのRecv-QがSend-Qの値に張り付いている 該当しない場合 ListenOverflowsが増えていなければこの原因ではない。接続は確立したのにロードが終わらなければ「ログイン殺到とN+1クエリ」、ちょうど一定の人数で入れなくなるなら「ファイルディスクリプタの上限」 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件 listen(2) — Linux manual page Linux man-pages listenのbacklogはsomaxconnを超えると黙って切り詰められる、somaxconnのデフォルトは4,096(5.4から。以前は128)、キューが満杯のときは要求を無視してクライアントの再試行に任せることがある IP Sysctl Linux kernel tcp_syn_retries:接続要求(SYN)を、最初の再送待ちを1秒として何度か再送、tcp_abort_on_overflowはデフォルトで無効(あふれても拒否の応答を返さない)、tcp_syncookiesはデフォルトで有効 listen function (winsock2.h) Microsoft Windowsではキューが満杯になると、クライアントがWSAECONNREFUSEDエラーを受け取る SNMP counter Linux kernel TcpExtListenOverflows:acceptキューが満杯で接続要求(SYN)を破棄した回数、このときTcpExtListenDropsも一緒に増える net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel ssのRecv-Q・Send-Qの値:リッスンソケットではacceptを待っている接続数とbacklogの上限、接続済みソケットではアプリがまだ読んでいないバイト数とACKを受け取っていない送信バイト数
ファイルディスクリプタの上限 File descriptor limit (ulimit)
ID so-fd · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
接続ごとにファイルディスクリプタ(fd。OSが開いているファイルやソケットに付ける番号)が必要ですが、1つのプロセスが開けるfdの数には上限があります。
なぜ 同時接続数がプロセスのファイルディスクリプタ上限に到達 → すると サーバーが新しい接続を受け付けられない(Too many open files)。ログファイルやDB接続を開く処理も同時に失敗 → 画面では ちょうど一定の人数から先は誰も入れない接続不可・無限ロード
症状 接続不可・無限ロード
要因 パケットロス
誰に起きるか サーバー全体
いつ 接続直後・メンテ明け, 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 接続を終えるときにソケットを確実に閉じる(fdリークの防止)、acceptがEMFILE(fd不足)で失敗したら接続の受け付けをしばらく止めるか、あらかじめ確保しておいた予備のfdで受け付けてすぐ閉じる(同じ接続通知だけを繰り返し処理してCPUを浪費しないように)。
インフラチームの対応 ulimit・サービス設定(systemdのLimitNOFILE)の確認、上限に近づいたときのアラート。
数値の目安 Linuxでは、サービスの設定を個別に変えない限り上限が1,024のままの場合がまだ多くあります。ゲームサーバーでは通常、数万〜数十万に引き上げます。Windowsにはこのような低いデフォルトの上限はありません。
グラフでは 上限で頭打ち · プロセスが開いているfd数、同時接続数
確認箇所 pidstat -vでゲームサーバープロセスのfd-nr(開いているファイルディスクリプタ数)を、/proc/PID/limitsで開けるファイル数の上限を確認し、サーバーログからacceptの失敗(EMFILE、Too many open files)を探す 該当する場合 fd数が上限値で頭打ちになり、その時刻からacceptがEMFILEで失敗している 該当しない場合 fd数が上限に遠く及ばなければこの原因ではない。接続要求がカーネルで破棄されていれば「接続待ちキュー(backlog)のあふれ」、接続追跡の問題なら「サーバーのconntrackテーブル飽和」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 受け付けられなかった接続はカーネルの接続待ちキュー(backlog)にそのまま残るため、サーバーのコードによっては「新しい接続あり」の通知を受け続けてCPUを浪費することもあります。
出典5件
ID so-sockbuf · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
送受信バッファが小さいと、バーストトラフィックが集中したときに、UDPで受信したパケットは破棄され、TCPの送信はバッファに空きがなくブロックされます。
なぜ SO_SNDBUF・SO_RCVBUFがデフォルト値のまま、または小さすぎる → すると バーストや、受信スレッドが一瞬止まった間にUDPの受信バッファがあふれて破棄、TCPは送信バッファに空きがなく待機 → 画面では ワープ(UDPのパケットロス)または早送り(TCPの待機)
症状 ワープ , 早送り
要因 パケットロス, ストール
誰に起きるか サーバー全体
いつ 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 トラフィックに見合ったバッファサイズ(SO_SNDBUF・SO_RCVBUF)をコードで設定、TCPはサイズを明示するとLinuxの自動サイズ調整が無効になるので注意、大きくしすぎると古いデータがバッファにたまって遅延が増えるので適度に、受信スレッドが止まらないようにする。
インフラチームの対応 カーネルの上限(rmem_max・wmem_max。コードで設定したバッファサイズもこの値を超えられない)とデフォルト値(rmem_default)の調整、バッファあふれのカウンター(RcvbufErrors)の監視。
数値の目安 LinuxのUDP受信バッファのデフォルト値は約208KBです。小さなパケットでも1個でカーネルメモリを実際のサイズよりはるかに多く消費するため、数十〜数百個で満杯になります。毎秒10万個を受信するサーバーなら、受信スレッドが数ms止まるだけであふれます。
グラフでは 不定期なスパイク · UDP受信バッファのあふれ(UdpRcvbufErrors)
確認箇所 nstat -azでUdpRcvbufErrorsの増加量を、ss -uamnでskmem(rbは受信バッファサイズ、dはソケットに入れられず破棄したパケット数)を確認し、TCPはss -tmのskmemで送信待ちメモリ(w)が送信バッファサイズ(tb)に達しているかを確認 該当する場合 バーストや受信スレッドが止まった時刻にUdpRcvbufErrors(またはソケットのd)が増え、rbがデフォルト値(約208KB)付近。TCPはwがtbに張り付いたままsendがブロック 該当しない場合 カウンターが増えていないのにパケットロスがあれば、NICの段階(「リングバッファ不足」)かネットワーク区間 確認手段 インフラのツールで確認(ゲームコード不要)
出典6件
スレッド過多とコンテキストスイッチ Thread oversubscription, context switching
ID so-context · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
コア数よりはるかに多いスレッドを動かすと、OSがそれらを切り替えて実行するだけでCPUを消費します。
なぜ 接続ごとにスレッドを作るなどして、スレッドが数百〜数千個 → すると コンテキストスイッチ(実行するスレッドの切り替え)のコストとキャッシュミスが増加 → 画面では CPUはビジーなのにスループットは低く、ティックがばらついてカクつき・スローモーション
症状 カクつき , スローモーション
要因 ストール, ジッター
誰に起きるか サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 コア数に合わせたスレッド数、非同期I/O(epoll・IOCP)。
インフラチームの対応 コンテキストスイッチ回数と実行待ちスレッド数(vmstatのcs・r)の監視。
数値の目安 コンテキストスイッチは1回あたり数µsで、その後のキャッシュミスのコストまで含めるとさらに大きくなります。
グラフでは 人数・負荷に連動して上昇 · 毎秒のコンテキストスイッチ数、実行待ちスレッド数
確認箇所 vmstat 1のcs(毎秒のコンテキストスイッチ数)・r(実行中またはCPU待ちの数)をコア数と比較し、pidstat -w -tでゲームサーバーのスレッドごとの自発的(cswch/s)・非自発的(nvcswch/s)コンテキストスイッチを確認 該当する場合 同時接続数が増えるとrがコア数を大きく上回り、csも急上昇し、非自発的コンテキストスイッチの多いスレッドが数百個ある 該当しない場合 rがコア数以下にとどまればこの原因ではない。自発的なスイッチだけが多ければ、スレッドがロックやI/Oを待っている(「ロック競合」「ブロッキングI/O構造」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID so-steal · 主担当 インフラチーム・サーバーインフラ · 副担当 外部・外部
物理サーバー(ハイパーバイザー)が仮想マシンのCPU時間を一時的にほかの仮想マシンに回している間(CPUスチール)、ゲームサーバーが止まります。
なぜ 同じホスト上のほかの仮想マシンがCPUを大量に使用 → すると 自分の仮想マシンが数ms〜数十msずつ実行機会を失う → 画面では 原因不明のティック時間の急増で、カクつき・フリーズ
症状 カクつき , フリーズ
要因 ストール
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ · 副担当 外部・外部
インフラチームの対応 steal指標(top・vmstatのst)の監視、専用コア・専有ホスト、CPUクレジットが尽きると遅くなるバースト可能インスタンスを避ける、stealが高止まりするインスタンスは停止してから起動し直し、別のホストへ移す。
外部の対応 stealが高止まりするホストをクラウド事業者に報告。
グラフでは 不定期なスパイク · %steal、サーバーのティック時間
確認箇所 mpstat -P ALL 1の%stealを、サーバーのティック時間と同じ時間軸に並べて確認 該当する場合 ティックが跳ねた時刻に%stealも跳ね、停止してから起動し直して別のホストに移すと減る 該当しない場合 %stealが0に近いのにティックが跳ねるなら、ゲームサーバー内部の原因(「サーバーGCの全停止」「ロック競合」)。コンテナなら「コンテナのCPUスロットリング(CFSクォータ)」 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID so-cpu-quota · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
コンテナにCPU上限をかけると、決まった周期(通常100ms)の中でクォータを使い切った時点から、残りの時間は強制的に止められます(スロットリング)。
なぜ Kubernetesなどで、ゲームサーバーのコンテナにCPU上限(limit)を設定している → すると ティックの計算が集中した瞬間にクォータを使い切り、次の周期まで数十ms停止 → 画面では 平均CPUは低いのにティックが周期的に跳ねて、カクつき・スローモーション
症状 カクつき , スローモーション
要因 ストール, ジッター
誰に起きるか サーバー全体
いつ 人が集中したとき, ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ワーカースレッド数をCPU上限に合わせる(ランタイムがホスト全体のコア数分のスレッドを作らないように)。
インフラチームの対応 CPU上限に余裕を持たせるか、上限を外して専用コアを割り当てる、スロットリング回数(nr_throttled)の監視。
数値の目安 上限2コアのサーバーでスレッド8個が同時に動くと、100ms周期のクォータを25msで使い切り、残りの75msは止まります。
グラフでは 人数・負荷に連動して上昇 · スロットリング回数(nr_throttled)、サーバーのティック時間
確認箇所 コンテナのcgroupのcpu.statで、nr_throttled・throttled_usec(cgroup v1ではnr_throttled・throttled_time)の増加量をサーバーのティック時間と並べて確認 該当する場合 平均CPU使用率は上限より低いのにnr_throttled・throttled_usecが増え続け、ティックが跳ねた時刻と重なる 該当しない場合 nr_throttledが増えなければこの原因ではない。仮想マシン自体が待たされているなら「CPUスチール(仮想マシン)」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID so-cstate · 主担当 インフラチーム・サーバーインフラ
使われていないCPUコアは、電力を節約するために深い省電力状態(C-state)に入り、周波数も下げます。パケットやタイマーが来ると、復帰して周波数を上げるまでに時間がかかるため、小さなパケットの処理に遅延が加わります。
なぜ OSの周波数制御ポリシー(governor)やBIOSの電源設定が、深いC-stateと低い周波数を許可している → すると 休んでいたコアが深い省電力状態から復帰するたびに最大数百µs遅れ、周波数が低く固定されているとティックの計算自体が遅くなる → 画面では 普段は体感しにくいが、サーバー間の呼び出しが多いと積み重なり、空いているときにかえって応答が遅くなる入力遅延。周波数が低く固定されていると、人が集中したときにティックが遅れてスローモーション
症状 入力遅延 , スローモーション
要因 遅延, ジッター, ストール
誰に起きるか サーバー全体
いつ 常に, ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 BIOSの電源設定を性能重視に、OSのgovernorをperformanceに(cpufreqのscaling_governor)、遅延に敏感なサーバーでは深いC-stateを制限(tunedのlatency-performanceプロファイル、PM QoSの/dev/cpu_dma_latency、カーネルパラメータintel_idle.max_cstate)、変更後は同じデータセンター内の往復時間・ティック時間のジッターと消費電力を合わせて比較。
数値の目安 Linux 6.12のintel_idleドライバーにある表によると、IntelのサーバーCPUの浅いC1は復帰に1〜2µs、深いC6は133µs(Skylake-SP)〜290µs(Sapphire Rapids)かかります。1回あたりはわずかですが、1つのリクエストが複数のサーバーを経由すると、その分だけ積み重なります。カーネルは予想されるアイドル時間が長いほど深い状態を選ぶため、パケットがまばらにしか来ない空いたサーバーほど頻繁に起きます。汎用cpufreqのpowersave governorは、許可された範囲で最も低い周波数に固定します(intel_pstateにある同じ名前のアルゴリズムは、負荷に応じて調整します)。
グラフでは 最初から常に高い · 同じデータセンター内の往復時間、コアの周波数
確認箇所 cpupower monitorでコアごとのC-state滞在率と実際の周波数を確認し、/sys/devices/system/cpu/cpu0/cpuidle/以下の各stateのname・latency(復帰にかかるµs)・usage、cpufreqのscaling_governor、tuned-adm activeで現在のプロファイルを確認 該当する場合 空いているときにコアが最も深いC-stateに長くとどまるか、周波数が最低付近に固定されており、performance governor・浅いC-stateに変えると小さなリクエストの往復時間とジッターが減る 該当しない場合 変えても差が数十µs以内なら、この原因は無視してよい。ms単位で跳ねるなら「CPUスチール(仮想マシン)」かほかの層 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく オンプレミスのベアメタルサーバーでは、BIOS(ファームウェア)の電源設定とOSの設定を両方確認します。クラウドでは一部のインスタンスタイプだけがOSからC-state・周波数を変更でき、AWSはデフォルト設定が最大性能寄りなので、ほとんどの場合はそのままで構いません。Red Hat系のtunedにあるlatency-performanceプロファイルは、governorをperformanceにし、PM QoSで浅いC-stateだけを使うようにします。省電力を無効にすると消費電力が増えるため、遅延に敏感なサーバーだけに適用します。
出典7件
OOM Killer Out-of-memory killer
ID so-oom · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
Linuxはメモリが尽きると、メモリを最も多く使っているプロセスを選んで強制終了します。たいていはゲームサーバーです。
なぜ リークや急増でメモリが枯渇、またはコンテナのメモリ上限に到達 → すると カーネルがゲームサーバーのプロセスを強制終了 → 画面では そのサーバーの全員が同時に切断、直近の進行がロールバックされることもある
症状 切断 , 不発・ロールバック
要因 ストール
誰に起きるか サーバー全体
いつ 長時間稼働するほど, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 リークの修正、メモリ使用量に上限を設け、近づいたらデータを保存して正常終了する手順。
インフラチームの対応 メモリのアラート、コンテナのメモリ上限を実際の使用量に合わせて設定、先に終了させる順序の調整(oom_score_adj)。
数値の目安 カーネルログ(dmesg)に「Out of memory: Killed process」が残り、KubernetesではOOMKilledと表示されます。WindowsにはOOM Killerがなく、メモリ確保に失敗してサーバーがエラーで落ちることが多いです。
グラフでは 接続が一斉に切れる · 接続数、メモリ使用量
確認箇所 dmesgの「Out of memory: Killed process」の記録、KubernetesならPodステータスのOOMKilled、cgroup v2ならmemory.eventsのoom_killの増加を、接続が切れた時刻と突き合わせて確認 該当する場合 接続が一斉に切れた時刻にゲームサーバーのプロセスをkillした記録があり、その直前までメモリ使用量が上限に向かって上がっている 該当しない場合 OOMの記録がないのにプロセスが落ちていれば、「サーバークラッシュ」の手順でクラッシュログ・コアダンプを確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
メモリの回収・コンパクションによる停止 Memory compaction / reclaim stalls (THP)
ID so-reclaim · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
OSがヒュージページ(huge page)を作るためにメモリをコンパクションしたり、空きメモリを回収したりしている間、プロセスが止まります。
なぜ 空きメモリが減る、またはヒュージページ機能(THP)がメモリのコンパクションを実行 → すると メモリを要求したスレッドが、回収・コンパクションが終わるまで待機 → 画面では 不規則なサーバーの停止(数ms〜数百ms)
症状 フリーズ , カクつき
要因 ストール
誰に起きるか サーバー全体
いつ 長時間稼働するほど, ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 実行中の大きなメモリ確保を減らす(起動時にまとめて確保して再利用)。
インフラチームの対応 ヒュージページ(THP)は必要な箇所だけで使うように設定(madvise)、空きメモリの基準を引き上げる(vm.min_free_kbytesなど)。
グラフでは 不定期なスパイク · サーバーのティック時間、メモリPSI
確認箇所 /proc/pressure/memoryのsome・full(メモリ待ちで停止した時間の割合)と/proc/vmstatのcompact_stallの増加量をサーバーのティック時間と並べて確認し、/sys/kernel/mm/transparent_hugepage/defragの設定を確認 該当する場合 ティックが跳ねた時刻にメモリPSIが上がり、compact_stallが増える。defragがalways 該当しない場合 PSIとcompact_stallが変わらなければこの原因ではない。スワップの使用量が増えていれば「スワップ」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID so-timejump · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
サーバーの時刻が一度に数秒前後に調整されると、システム時刻に依存するタイマーが一斉に発火したり止まったりします。
なぜ 時刻同期が時刻を一度に大きく調整 → すると タイマーがまとめて発火したり止まったりし、タイムアウトが誤って判定される → 画面では バフ・クールタイムの異常、一斉に切断、早送り
症状 早送り , 切断 , 不発・ロールバック
要因 ストール
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 経過時間・タイムアウト・クールタイムは、飛んだり戻ったりしないモノトニッククロック(monotonic clock)で計算、ウォールクロック(wall clock)は表示・記録用に限る。
インフラチームの対応 時刻は徐々に調整(chronyのmakestepは起動直後だけ)、時刻同期の状態(時刻のずれ)の監視。
数値の目安 ntpdは差が0.128秒を超えると一度に合わせ、それより小さければ、1秒の差を解消するのに30分余りかかる速度で徐々に合わせます。最近よく使われるchronyは、推奨設定(makestep)では起動直後の数回だけ一度に合わせ、それ以降は徐々に合わせます。仮想マシンが一時停止から復帰したときにも時刻が飛びます。
グラフでは 不定期なスパイク · タイマーの発火数・切断数、時刻調整の記録
確認箇所 時刻同期サービスのログから時刻を一度に大きく調整した記録を探し、異常が起きた時刻と突き合わせる。chronyはlogchangeで指定した値(デフォルト1秒)より大きく調整するとsyslogに記録 該当する場合 バフ・クールタイムの異常、一斉の切断、早送りが起きた時刻に時刻調整の記録があり、調整幅が異常の大きさと近い 該当しない場合 時刻調整の記録がなければこの原因ではない。仮想マシンなら一時停止から復帰した場合(「クラウドホストのメンテナンス・ライブマイグレーション」)も確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
定期実行ジョブ Cron jobs (log rotation, backup, scans)
ID so-cron · 主担当 インフラチーム・サーバーインフラ
毎日同じ時刻に動くログ圧縮・バックアップ・セキュリティスキャンが、CPUとディスクを占有します。
なぜ 決まった時刻にOSのジョブが実行される → すると CPU・ディスクをゲームサーバーと取り合う → 画面では 毎日早朝4時のように、決まった時刻にカクつき・スローモーション
症状 カクつき , スローモーション
要因 ストール
誰に起きるか サーバー全体
いつ 一定の周期で
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 ジョブの実行時刻を分散、優先度を下げる(nice、ionice)、ゲームサーバーから切り離す(別のサーバーで実行)。
グラフでは 周期的なスパイク · CPU使用率、ディスクI/Oキュー、サーバーのティック時間
確認箇所 crontabとsystemctl list-timersで定期実行ジョブの実行時刻を集め、ティックが跳ねた時刻にpidstat -u -dでどのプロセスがCPU・ディスクを使っているかを確認 該当する場合 ティックが毎日(または毎時)同じ時刻に跳ね、その時刻に定期実行ジョブのプロセスがCPU・ディスクを占有している 該当しない場合 跳ねる時刻が毎日の決まった時刻と一致しなければこの原因ではない。数秒・数分の間隔で跳ねるなら「サーバーGCの全停止」「タイマーの一斉発火」 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID so-os-update · 主担当 インフラチーム・サーバーインフラ
ゲームのコードは変わっていないのに、サーバーのOS・カーネル・ドライバー・ファームウェアをアップデートしてから遅くなるケースです。アップデートによって、デフォルト値、スケジューラー、CPU脆弱性の緩和策(mitigations)、ドライバーの動作が変わることがあります。
なぜ 定期的なセキュリティパッチや新しいサーバーイメージで、カーネル・ドライバー・ファームウェアが変わる → すると デフォルト値やスケジューラーが変わったり新しい脆弱性の緩和策が有効になったりして、同じ処理により多くのCPU時間がかかり、スレッドにCPUが割り当てられる順序も変わる → 画面では 問題なかったサーバーがアップデートした日から常に少し遅くなって入力遅延、人が集中するとカクつき・スローモーション
症状 入力遅延 , カクつき , スローモーション
要因 遅延, ストール, ジッター
誰に起きるか サーバー全体
いつ 常に, 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 アップデートは一部のサーバーに先に適用し、ティック時間・遅延・CPU使用率を以前のバージョンと比べてから範囲を広げる、ゲームのアップデートとは別の日にデプロイ、アップデート前後のカーネル・ドライバー・ファームウェアのバージョンと主要なsysctlの値を記録、問題が出たら以前のカーネルで起動して確認、緩和策を無効にする設定(mitigations=off)はセキュリティリスクを検討して決める。
数値の目安 カーネルのバージョンが変わると、デフォルトの動作も変わります。たとえばLinuxは6.6以降、スケジューラーをCFSからEEVDFへ移行し始め、接続待ちキューの上限(somaxconn)のデフォルト値も5.4で128から4,096に変わりました。CPU脆弱性の緩和策は、カーネルからプログラムに戻るとき(システムコールを終えるたび)や、コンテキストスイッチ・仮想マシンの切り替えのときにCPU内部のバッファを消去するなどの処理を追加するため、パケットごとにシステムコールを呼ぶネットワークサーバーほど影響を受けます。一部の脆弱性は、完全に防ぐにはSMT(1つのコアを2つのスレッドのように使う機能)を無効にする必要があり、SMTを無効にすると処理内容によっては性能が大きく下がります。カーネルパラメータmitigations=offはこれらの緩和策をすべて無効にして性能を取り戻しますが、脆弱性にさらされます。
グラフでは ある時点から階段状に上昇 · サーバーのティック時間、CPU使用率、同じ負荷での遅延
確認箇所 パッケージマネージャーのアップデート履歴と再起動時刻、uname -rで確認したカーネルバージョン、ethtool -iで確認したNICドライバーの情報を、遅延が上がった時刻と突き合わせる。アップデートしたサーバーとしていないサーバーを同じ負荷でmpstat・pidstatを使って比較し、/sys/devices/system/cpu/vulnerabilities/の緩和策の状態も比較 該当する場合 遅延・CPU使用率が、アップデート後に再起動した時刻から一段上がってそのまま続き、同じ負荷でアップデートしたサーバーだけが高い。以前のカーネル・ドライバーで起動すると元に戻る 該当しない場合 アップデートしたサーバーとしていないサーバーが同じ負荷で同じように遅ければこの原因ではない。同じ日にゲームのアップデートもデプロイし、ユーザーあたりのパケット数・サイズが変わっていれば「アップデートによるトラフィックパターンの変化」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 緩和策の状態は/sys/devices/system/cpu/vulnerabilities/以下のファイルで確認します。デフォルト(mitigations=auto)はSMTを有効にしたまま緩和しますが、auto,nosmtにすると脆弱なCPUではSMTを無効にするため、カーネルを更新した後に論理コア数が半分に減ることがあります。ゲームのアップデートと同じ日にOSをアップデートすると原因の切り分けが難しくなるので、別々にデプロイします。
出典6件
ID so-conntrack · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
Linuxのファイアウォールがすべての接続を記録する接続追跡(conntrack)テーブルが上限に達すると、新しいパケットを破棄します。
なぜ 接続の殺到や短い接続の繰り返しで、接続の記録が増加 → すると テーブルが満杯になり、新しい接続と一部のパケットを破棄 → 画面では 接続不可、原因不明のパケットロスでワープ
症状 接続不可・無限ロード , ワープ
要因 パケットロス
誰に起きるか サーバー全体
いつ 接続直後・メンテ明け, 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:短い接続を減らす(サーバー間の呼び出しは接続を再利用)。クライアント:接続に失敗したり切れたりしたら、再試行の間隔を広げながらランダムに分散。
インフラチームの対応 テーブルサイズ(nf_conntrack_max)を増やす、ゲームのポートは追跡の対象外にする(rawテーブルのNOTRACK)、使用量のアラート。
数値の目安 デフォルトの上限はサーバーのメモリ量に応じて約6万〜26万件です。あふれるとカーネルログに「nf_conntrack: table full, dropping packet」が出力されます。
グラフでは 上限で頭打ち · conntrackのエントリ数(nf_conntrack_count)
確認箇所 sysctlのnet.netfilter.nf_conntrack_count(現在のエントリ数)をnf_conntrack_maxと同じグラフに並べ、dmesgで「nf_conntrack: table full, dropping packet」を探す 該当する場合 nf_conntrack_countがmaxで頭打ちになり、その時刻からカーネルログにtable fullが出ている 該当しない場合 エントリ数がmaxに遠く及ばなければこの原因ではない。AWSインスタンス自体の接続追跡の上限は、「クラウドのPPS上限超過」にあるconntrack_allowance_exceededで確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID so-ports · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲームサーバーがDBやほかのサーバーへの接続を短時間で頻繁に張っては切ると、切れた接続がしばらくポートを占有し、新しい接続を開けなくなります。
なぜ リクエストごとに新しい接続を開いて閉じる → すると 先に閉じた側が約60秒(Linux)の間ポートを占有し(TIME_WAIT)、使えるポートが尽きる → 画面では 内部リクエストが失敗し、保存の失敗・機能のエラー
症状 不発・ロールバック , 接続不可・無限ロード
要因 パケットロス
誰に起きるか サーバー全体, 特定の機能だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 接続の再利用(コネクションプール)、リクエストごとに接続を開いて閉じないようにする。
インフラチームの対応 ポート範囲の拡大(ip_local_port_range)、外向き接続でのTIME_WAITの再利用(Linuxのtcp_tw_reuse)の検討、TIME_WAIT数の監視。
数値の目安 Linuxのデフォルトのポート範囲(32768〜60999)は約2万8千個です。同じ接続先に1秒あたり470回を超えて新しく接続すると尽きます。Windowsはデフォルトのポートが約1万6千個(49152〜65535)で、TIME_WAITも長いため、さらに早く尽きます。
グラフでは 上限で頭打ち · TIME_WAITソケット数、内部接続の失敗数
確認箇所 ss -tan state time-waitでTIME_WAITソケットを接続先アドレスごとに数え、ゲームサーバーのログからconnectの失敗(EADDRNOTAVAIL)を探す 該当する場合 同じ接続先(DBなど)へのTIME_WAITがエフェメラルポートの範囲(デフォルトで約2万8千個)付近で頭打ちになり、connectがEADDRNOTAVAILで失敗している 該当しない場合 TIME_WAITが少ないのに外部への接続だけが失敗するなら「クラウドのNATゲートウェイの接続・ポート上限」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく LinuxのTIME_WAITの60秒は、カーネルに固定された値です。名前の似たtcp_fin_timeoutを短くしても、TIME_WAITは短くなりません。
出典5件
L8 ソケットとプロトコル
原因14件 · メインページの章
ID sk-hol · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
TCPは順序を守るため、失われたパケットを1つ受け取り直すまで、後から届いたパケットをゲームに渡しません。
なぜ パケットが1つ消失 → すると 後続のパケットは届いているが、受信バッファで待機 → 画面では 止まった後に一気に解放されて早送り
症状 フリーズ , 早送り
要因 パケットロス, ストール
誰に起きるか 自分だけ
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:リアルタイムの位置はUDP、どうしても必要なものだけ信頼性のある送信、ストリームを複数に分ける。クライアント:サーバーと同じ方式(UDP、チャネル分離)にネットワーク処理を変更。
数値の目安 パケットを1つ失うと最低でも往復時間+α、再送パケットまで失うと数百ms〜数秒止まります。
グラフでは 途切れた後にまとめて到着 · 接続ごとの受信量、再送数
確認箇所 サーバー側のパケットキャプチャ(tcpdump・Wireshark)で、そのユーザーの接続の再送パケットとその前後の空白を確認し、サーバー全体はnstat -azでTcpRetransSegsの増加量を確認 該当する場合 止まった区間がパケット1つの再送から始まり、再送パケットが届いた直後にたまっていたデータが一気に処理される(受信量が0の状態から急増) 該当しない場合 UDPで通信するゲームなら該当しない。再送がないのに止まるなら、サーバーのティック側(「ティックバジェット超過」)を確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID sk-rto · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
再送がまた失敗するたびに待ち時間が2倍に延びるため、短い回線断が長い停止になります。
なぜ 回線が一瞬切れて、再送も続けて失敗 → すると 次の試行までの時間が0.3 → 0.6 → 1.2 → 2.4秒のように2倍ずつ延びる(Ping 100msの場合) → 画面では 回線が切れたのは1秒なのに、ゲームは2秒以上止まる。さらに長く切れると最終的に切断
症状 フリーズ , 切断
要因 パケットロス, ストール
誰に起きるか 自分だけ
いつ ときどきランダムに, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:ハートビートに応答し、一定時間受信がなければ接続を先に整理(TCP_USER_TIMEOUTであきらめるまでの時間を短縮)、セッショントークンでセッションを引き継ぐ、信頼性UDP。クライアント:短い間隔でハートビートを送り、応答が途絶えたらTCPの再送を待たずにすぐ再接続。
数値の目安 LinuxのRTO(再送待ち時間)は「Ping+200ms」が最小で、接続を確立するときは1秒から始まります。デフォルト設定(tcp_retries2=15)では、再送が失敗し続けても約15分後にようやく接続をあきらめます。
グラフでは 途切れた後にまとめて到着 · 接続ごとのRTO・backoff、RTOの満了回数
確認箇所 止まった接続をss -tiで確認してrto(再送待ちのms)とbackoff(連続満了回数)を、サーバー全体はnstat -azでTcpExtTCPTimeouts(再送タイマーの満了回数)の増加量を確認 該当する場合 止まった接続のbackoffが1以上で、rtoが秒単位まで大きくなっており、その時刻にTCPTimeoutsが増えている 該当しない場合 再送が高速再送で済み、RTOの満了がなければ停止は短い。その場合は「TCPのHOLブロッキング」 確認手段 インフラのツールで確認(ゲームコード不要)
出典6件
Nagleアルゴリズム+遅延ACK Nagle + delayed ACK (TCP_NODELAY off)
ID sk-nagle · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
小さなパケットをまとめて送るNagleアルゴリズムと、ACKを遅らせて送る遅延ACKがかみ合い、メッセージを分けて書き込むたびに40〜200msずつ遅延します。
なぜ TCP_NODELAYを有効にしないまま、小さなメッセージを分けて書き込む → すると 送信側はACKを待ち、受信側はACKを遅らせて送る → 画面では 回線のPingは低いのに、すべての操作が一様にもたつく入力遅延
症状 入力遅延
要因 遅延
誰に起きるか サーバー全体, 自分だけ
いつ 常に, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:TCP_NODELAYを有効にする、1ティック分のメッセージをまとめて一度に書き込む、受信側の遅延ACKを無効にする方法(LinuxのTCP_QUICKACKは一時的にしか維持されない、WindowsはPCごとにレジストリを変更)はゲーム側で確実に制御できないので頼らない。クライアント:TCP_NODELAYを有効にする、1フレーム分のメッセージをまとめて一度に書き込む。
数値の目安 遅延ACKは、Linuxでは通常40ms(状況によって最大200ms)です。Windowsは以前のバージョンが200msで、最近のバージョンは40msです(Windows Server 2019のデフォルトテンプレートは40ms)。遅延ACKは受信側のOSが決めるため、サーバーがNagleを有効にしたままメッセージを分けて送ると、受信するPCによって40〜200msずつ遅延することがあります。
グラフでは 最初から常に高い · 操作の応答時間(ゲーム内のRTT)
確認箇所 サーバー側のパケットキャプチャ(tcpdump・Wireshark)でリクエストとレスポンスの間隔を確認し、サーバー・クライアントのコードがTCP_NODELAYを有効にしているかを確認 該当する場合 回線のPingは低いのに、小さなパケットの間に40ms(Windowsの以前のバージョンは200ms)前後の空白が繰り返し現れ、その空白は相手のACKが届いた直後に終わる。TCP_NODELAYを有効にすると消える 該当しない場合 応答の間隔が回線のPingと同程度ならこの原因ではない。ゲームサーバーが応答を作るのが遅ければ、サーバーの処理側(「メッセージキューの滞留」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
ID sk-block-send · 主担当 ゲーム開発チーム・サーバー開発
回線の遅い1人の送信バッファが満杯なのに、ブロッキング方式(バッファに空きができるまで呼び出しが戻らない送信)で送ると、サーバーのスレッドがその1人を待ちます。
なぜ 遅いクライアントの送信バッファが満杯 → すると ブロッキング送信のため、サーバーのスレッドがバッファに空きができるまで待機 → 画面では そのスレッドが担当する全員がフリーズ・スローモーション
症状 フリーズ , スローモーション
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ ときどきランダムに, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ノンブロッキング送信、クライアントごとの送信キューの上限、古い更新の破棄。
グラフでは 不定期なスパイク · サーバーのティック時間、接続ごとのSend-Q
確認箇所 ss -tnで、接続ごとのSend-Q(ACKを受け取っていないか、まだ送れていないバイト)が送信バッファいっぱいまでたまった接続を探し、ティックが跳ねた瞬間のゲームサーバーのスレッドダンプ(スタック)で、send呼び出しで止まっているスレッドがあるかを確認 該当する場合 Send-Qが満杯の遅い接続があるとき、その接続を担当するスレッドがsendで止まっており、同じスレッドが担当する人たちだけが一緒に止まる 該当しない場合 止まったスレッドがsend以外(ロック、DB呼び出し)で待っていれば「ロック競合」「ゲームスレッドの同期呼び出し」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID sk-slow-client · 主担当 ゲーム開発チーム・サーバー開発
送るデータがたまり続けるクライアントに対して、サーバーが古い更新を破棄したり接続を切ったりします。
なぜ クライアントの回線が、サーバーが送る量に追いつかない → すると サーバーが古い更新を破棄するか、上限を超えたら接続を切断 → 画面では その人だけワープまたは切断
症状 ワープ , 切断
要因 パケットロス
誰に起きるか 自分だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 送る量を減らす(距離に応じた更新頻度)、品質を下げて送り続ける、カーネルにためておく量を減らす(LinuxのTCP_NOTSENT_LOWAT)。
数値の目安 送信バッファが256KBだと、30KB/sの回線では8秒以上分の送れていないデータがたまります。Linuxはこのバッファを自動で数MBまで大きくすることもあります。
グラフでは 一部だけ高い · 接続ごとのSend-Q、クライアントごとの破棄した更新の数
確認箇所 ゲームサーバーが記録するクライアントごとの送信キューの長さ・破棄した更新の数・切断理由を確認し、サーバーでss -tniを使ってその接続のSend-Qとcwndを合わせて確認 該当する場合 ワープしたり切断されたりした人の接続だけSend-Qがたまり続け、ゲームログにその人の更新の破棄や、送信キューの上限超過による切断が記録されている 該当しない場合 Send-Qが空なのにワープするなら、サーバーの送信側の問題ではない。その人の回線のパケットロス(「無線区間のパケットロス」)か画面の補間側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件 IP Sysctl Linux kernel tcp_wmem:自動調整される送信バッファの最大値はデフォルト64KB〜4MB(メモリ量による)、tcp_notsent_lowat・TCP_NOTSENT_LOWATでまだ送っていないデータの量を制限 net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel ssのRecv-Q・Send-Qの値:リッスンソケットではacceptを待っている接続数とbacklogの上限、接続済みソケットではアプリがまだ読んでいないバイト数とACKを受け取っていない送信バイト数
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接続が残っており、そのアカウントの再接続が「すでに接続中」で拒否されている 該当しない場合 長時間無通信の接続がないのに「すでに接続中」が出るなら、ゲームサーバーのセッション整理のコード側 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID sk-fragment · 主担当 ゲーム開発チーム・サーバー開発
MTU(一度に送れるサイズ)を超えるUDPパケットはIP層でフラグメント化され、フラグメントを1つ失うだけでパケット全体が破棄されます。
なぜ 人の多い場所のスナップショットが1,500バイトを超える → すると 複数のフラグメントに分割して送信、1つでも失うと全体を破棄 → 画面では 大きなパケットほどロス率が数倍になる。混雑した場所でだけワープ
症状 ワープ
要因 パケットロス
誰に起きるか 特定の場所・チャンネル, 特定の地域・ISP
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 パケットを1,200バイト以下に自前で分割、変更分だけを送る。
数値の目安 ロス率2%の回線では、4つのフラグメントに分かれたパケットの約8%が失われます。フラグメント化されたパケットを一律に破棄するファイアウォールや通信事業者もあり、その場合ユーザーは大きなパケットを1つも受け取れません。
グラフでは 人数・負荷に連動して上昇 · IPフラグメンテーションの数(IpFragCreates)、スナップショットのサイズ
確認箇所 サーバーでnstat -azのIpFragCreates(送信時に作ったフラグメント数)の増加量を確認し、受信側ではIpReasmFails(再構築の失敗数)を確認。ゲームサーバーのログやパケットキャプチャでUDPパケットのサイズ分布を確認 該当する場合 人が集中する場所でIpFragCreatesが増え、1,500バイトを超えるUDPパケットがあり、そのときワープの報告が増えている 該当しない場合 IpFragCreatesが増えなければ、サーバーの送信側ではフラグメンテーションは起きていない 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
信頼性UDPの再送設定 Reliable-UDP tuning (KCP, ENet…)
ID sk-reliable-udp · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
UDPの上に独自に作った再送ルールが保守的すぎると復旧が遅れ、攻撃的すぎると回線をさらに詰まらせます。
なぜ 再送の間隔・回数・ウィンドウサイズの設定が回線に合っていない → すると 復旧の遅れ、または重複送信による輻輳の悪化 → 画面では スキル不発、早送り、輻輳時にさらにひどいラグ
症状 不発・ロールバック , 早送り
要因 パケットロス, 遅延
誰に起きるか 自分だけ
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:測定した往復時間に基づく再送、重要度ごとのチャネル分離。クライアント:サーバーと同じ再送・チャネル設定を適用。
グラフでは 不定期なスパイク · 信頼性UDPの再送率、ゲーム内のRTT
確認箇所 使っているライブラリが接続ごとに持つ統計(再送数、推定往復時間、再送待ち時間)をサーバー・クライアントで記録し、同じユーザーの実際の回線のロス率(mtrで測った値)と比較 該当する場合 再送率が実際の回線のロス率より数倍高ければ攻撃的すぎる設定、再送待ち時間が測定した往復時間の数倍なら保守的すぎる設定 該当しない場合 再送率が回線のロス率と同程度で、待ち時間が往復時間に見合っていれば設定の問題ではない。回線のパケットロスそのものを確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典1件
ID sk-slowstart · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
TCPはしばらくアイドル状態が続くと輻輳ウィンドウ(一度に送れる量)を再び縮めるため、急に大きなデータを送るときに何回かに分けて送ります。
なぜ アイドル状態だった接続で、街への入場など大きなデータを送る → すると 輻輳ウィンドウが縮んでいるため、複数の往復に分けて送信 → 画面では 入場直後、周りのキャラクターやNPCが往復数回分遅れて表示される(遠いサーバーほど目立つ)
症状 入力遅延 , 表示されない・ゴースト
要因 遅延
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時, しばらく放置した後
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 入場時のデータを減らす(どうしても必要なものから先に送る)。
インフラチームの対応 tcp_slow_start_after_idleを無効にする(Linux、サーバー全体の設定)。
数値の目安 RTOより長くアイドル状態が続くと輻輳ウィンドウが縮み始め、長くアイドルだった場合は約14KB(パケット10個)まで下がります。そうなると100KBは一度に送れず、3往復に分けて送ることになります。
グラフでは 一部だけ高い · 入場直後の送信時間(RTTが長いユーザー)
確認箇所 sysctl net.ipv4.tcp_slow_start_after_idleの値を確認し、アイドル後にエリアへ入場した瞬間、その接続のss -tiでcwnd(輻輳ウィンドウ)が小さくなっているかを確認 該当する場合 設定が1(デフォルト)で、アイドル後の入場の瞬間にcwndが10前後まで縮み、送信が複数の往復に分かれる。RTTが長いユーザーほど遅れて表示され、0に変えると解消する 該当しない場合 cwndが大きいまま維持されているのに遅れて表示されるなら、サーバー側の入場処理(「密集エリア進入時のスポーン集中」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
輻輳制御による送信量の急減 Congestion control backoff
ID sk-congestion · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
TCPはパケットロスを輻輳のシグナルとみなし、送信速度を30〜50%落とします。Wi-Fiでのパケットロスにも同じように反応します。
なぜ 送る量が多いときに、Wi-Fiや回線でわずかなパケットロスが発生 → すると TCPが送信速度を大きく落とし、ゆっくり回復(Linux・WindowsのデフォルトであるCUBICは30%落とす) → 画面では 人の多い場所で更新が遅れて早送り・入力遅延
症状 早送り , 入力遅延
要因 遅延, ストール
誰に起きるか 自分だけ
いつ 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 送る量を減らす(関心領域、変更分だけ)、一度にまとめて送らないよう分けて送る。
インフラチームの対応 BBRのような輻輳制御に切り替える(tcp_congestion_control)。
グラフでは 徐々に上昇して急落 · 接続ごとの輻輳ウィンドウ(cwnd)・送信レート
確認箇所 更新が遅れたユーザーの接続をss -tiで何度か取得し、cwnd・ssthreshの変化と輻輳制御アルゴリズムの名前(cubic・bbr)を確認しながら、Send-Qがたまっていくかも合わせて確認 該当する場合 パケットロスの後にcwndが大きく縮んでからゆっくり上がることを繰り返し、縮んでいる間にSend-Qがたまり、早送り・入力遅延の報告時刻と重なる 該当しない場合 cwndに余裕があるのに遅れるなら、受信側のウィンドウ(「ゼロウィンドウ(再送のように見える停止)」)かサーバーの送信側 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
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で正常に終了しているのに理由が表示されなければ、クライアントの終了処理側 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID sk-blocking-io · 主担当 ゲーム開発チーム・サーバー開発
1つのソケットを待っている間、スレッドがほかの処理をできない構造では、人が増えるほど全体が遅くなります。
なぜ 接続ごとに読み書きを待つ方式 → すると 1つの接続の遅延が、同じスレッドのほかの接続に波及 → 画面では 同時接続数が増えるほど、全体がスローモーション・入力遅延
症状 スローモーション , 入力遅延
要因 ストール
誰に起きるか サーバー全体
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 epoll・IOCP・io_uringベースの非同期I/Oに移行。
グラフでは 人数・負荷に連動して上昇 · 応答時間、スレッド数
確認箇所 pidstat -w -tでゲームサーバーのスレッド数とスレッドごとの自発的コンテキストスイッチ(cswch/s。資源を待って止まった回数)を確認し、同時接続数に応じた応答時間と比較 該当する場合 同時接続数が増えるほど応答時間が急激に上がり、接続数に比例して増えたスレッドのほとんどが自発的スイッチばかり多く、CPUはほとんど使っていない(ソケット待ち) 該当しない場合 スレッドが待ちなしでCPUを使い続けていれば、計算の過負荷(「ティックバジェット超過」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID sk-reuseport · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
同じポートを複数のプロセスで分担して受け付けると、カーネルは接続ごとにアドレスのハッシュで担当プロセスを決め、その後は変更しません。担当プロセスが1つ止まると、そこに割り当てられた人だけが待たされます。
なぜ ゲートウェイ・ログインサーバーがSO_REUSEPORTで複数のプロセスを起動 → すると 1つのプロセスがGCや過負荷で止まっても、そこに割り当てられた新しい接続とUDPパケットはほかのプロセスに回されない → 画面では 一部の人だけ接続不可・フリーズ。プロセス数が変わる再起動時には、一部のUDPセッションが切れる
症状 接続不可・無限ロード , フリーズ , 切断
要因 ストール, パケットロス
誰に起きるか 自分だけ, サーバー全体
いつ 接続直後・メンテ明け, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 受信スレッドは絶対に止まらないようにする、再起動時にセッションを引き継ぐ手順を実装。
インフラチームの対応 プロセスごとの接続待ちキューの監視(ssのRecv-Q)、デプロイでプロセス数を変えるときはセッション引き継ぎの手順に従うようにする。
グラフでは 一部だけ高い · リッスンソケットごとの接続待ちキュー(Recv-Q)
確認箇所 ss -ltnpで、同じポートのリッスンソケットごとのRecv-Q(acceptを待っている接続数)と担当プロセスを確認し、プロセスごとのスループットを比較 該当する場合 同じポートの複数のソケットのうち1つだけRecv-Qがたまり続け、そのプロセスが止まっているかスループットが0に近い 該当しない場合 すべてのソケットのRecv-Qが均等にたまっていれば、全体の過負荷(「接続待ちキュー(backlog)のあふれ」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID sk-udp-connreset · 主担当 ゲーム開発チーム・サーバー開発
Windowsサーバーがすでに去ったクライアントにUDPを送ると、「ポート到達不能」(ICMP)の通知が返ってきます。その通知のせいで次の受信呼び出しがエラーで終わりますが、サーバーのコードがこのエラーをソケット自体の故障として扱うと、そのソケットを使っている全員が影響を受けます。
なぜ 出ていったばかりのクライアントのアドレスにUDPを送り続け、「ポート到達不能」(ICMP)の通知が返ってくる → すると Windowsが次の受信呼び出しをWSAECONNRESET(10054)エラーで終わらせ、サーバーのコードが受信を止めるかソケットを閉じる → 画面では そのソケットを使っていた全員が一斉にフリーズ・切断
症状 切断 , フリーズ
要因 パケットロス, ストール
誰に起きるか サーバー全体
いつ ときどきランダムに, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 WSAIoctlでSIO_UDP_CONNRESETを無効にしてこの通知を受け取らない、受信エラーが起きてもログだけ残して受信を続ける。
グラフでは 接続が一斉に切れる · 接続数、受信エラーのログ
確認箇所 ゲームサーバーのログからUDP受信のエラーコード(WSAECONNRESET、10054)と、受信ループが止まったりソケットを閉じたりした記録を探し、サーバー側のパケットキャプチャで直前にICMP Port Unreachableが届いたかを確認 該当する場合 接続が一斉に切れる直前にWSAECONNRESETの受信エラーが記録され、その前に、出ていったばかりのクライアントのアドレスからICMP Port Unreachableが届いている 該当しない場合 Linuxサーバーであるか、コードでSIO_UDP_CONNRESETを無効にしていれば該当しない 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
L9 サーバーのゲームプロセス
原因18件 · メインページの章
ID sp-tick-overrun · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
1ティックの処理がバジェットを超えるとサーバーのティック周期が延び、そのエリア全体がゆっくり進んだりカクついたりします。
なぜ 1ティック(例:50ms)で処理する仕事がバジェットを超える → すると 1秒に20回計算するはずのゲーム状態を8回しか計算できない → 画面では そのエリア全体がスローモーション(サーバーの設計によってはカクつき)、スキルの反応が遅い
症状 スローモーション , 入力遅延 , カクつき
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 重い計算を減らす、ティックを複数のスレッドに分割、人数の分散(チャンネル)、ティックの処理時間をメトリクスとして記録。
インフラチームの対応 ティック時間とコアごとのCPU使用率を監視・アラートに追加、シングルコア性能(クロック)の高いCPU・インスタンスを検討。
数値の目安 20ティックのサーバーのバジェットは50ms、30ティックは33ms、60ティックは16.7msです。急な集中に備えて、普段はバジェットの半分程度しか使わないよう余裕を持たせるほうが安全です。
グラフでは 人数・負荷に連動して上昇 · サーバーのティック時間、ゾーン・チャンネルごとの人数、ゲームスレッドのCPU
確認箇所 サーバーが記録するティック処理時間(p99)・ティック超過回数を、ゾーン・チャンネルごとの人数と同じグラフに並べて確認。ティックのメトリクスがなければ、pidstat -t 1でゲームスレッド1本のCPU使用率 該当する場合 人数が集中した時刻にティック時間がバジェット(20ティックなら50ms)を超え、その間ゲームスレッドのCPU使用率が100%近くに張り付いている 該当しない場合 ティックが超過しているのにゲームスレッドのCPUが低ければ、待ち側の原因(GC停止、ロック、同期呼び出し)。bccのrunqlatでランキューの待ち時間が長ければ、スレッドにCPUが割り当てられていないので、CPU不足・スレッド過多の側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく ティックが遅れたときの見え方は、サーバーの設計によって異なります。ティックごとにゲーム状態を決まった時間(例:50ms)だけ進めるサーバーでは、ゲーム内の時間そのものが遅くなってスローモーションになります。実際に経過した時間の分だけ一度に動かすサーバーでは、ゲームの進行速度は保たれますが、パケットがまばらになり一度に大きく動くため、カクつき・ワープに見えます。どちらの場合も入力の反応は遅れます。ゲームスレッド1つがサーバー全体を担当していればサーバー全体が、エリアごとにスレッドを分けていればそのエリアが遅くなります。EVE Onlineのように、大規模な戦闘でわざとゲーム内の時間を最大10倍まで遅くして(Time Dilation)計算を追いつかせるゲームもあります。
実際の事例 CCP Games 2014: EVE OnlineのHED-GP大規模艦隊戦でのサーバー過負荷
出典5件
ID sp-aoi · 主担当 ゲーム開発チーム・サーバー開発
誰が誰を見られるかを全員同士で比較すると、人数が10倍になったとき計算は100倍になります。
なぜ すべてのキャラクター同士で距離を比較しているか、グリッドに分割していても1つのセルの周辺に数百人が集中 → すると 100人なら約1万回、1,000人なら約100万回の比較 → 画面では ワールドボスや攻城戦のように人が集中した場所でティック時間が急増し、スローモーション・カクつき
症状 スローモーション , カクつき
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 グリッド・区域に分けて近くだけを比較、遠くの対象はまれに更新、1人が見る人数に上限。
数値の目安 距離の比較と、見える・見えないリストの更新を合わせて2人1組あたり0.1µs(1千万分の1秒)とすると、1,000人(約100万組)なら1ティックに100msかかります。20ティックのバジェット(50ms)の2倍です。
グラフでは 人数・負荷に連動して上昇 · サーバーのティック時間、1か所に集まった人数
確認箇所 ゾーン・チャンネルごとの人数とティック時間を同じグラフに並べ、ティック内で視界計算に使った時間を個別に計測した値を確認。個別の計測値がなければ、perf top -pでゲームプロセスの関数ごとのCPU比率 該当する場合 1か所に集まった人数が2倍になるとティック時間が4倍近くに増え、視界・距離計算の関数がCPU時間の大半を占めている 該当しない場合 ティック時間が人数に比例して増えるか、送信・シリアライズの関数の比率が大きければ、ブロードキャストの急増かシリアライズ・圧縮のコスト側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ブロードキャストの急増 Broadcast fan-out (N×N)
ID sp-broadcast · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
1人の動きを、その人が見えている全員に送ると、集まった人数の2乗に比例する数の更新を送ることになります。
なぜ 1人の変化を、それが見える全員に送信 → すると 1,000人が互いを見ていると、ティックごとに100万個の更新 → 画面では 送信キューと帯域幅が飽和して遅延・パケットロス(入力遅延・早送り・ワープ)
症状 入力遅延 , ワープ , 早送り
要因 遅延, パケットロス
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 距離・重要度に応じて更新頻度を下げる(近くの敵は毎ティック、遠くの人は1秒に数回)、1人に送る量に上限を設けて重要なものから詰める、複数の更新を1つのパケットにまとめる、表示人数の上限。
インフラチームの対応 サーバーごとの送信帯域幅・毎秒パケット数をNIC・インスタンスのネットワーク上限と比べてアラート、大規模イベントの前に余裕を確認。
数値の目安 1,000人 × 1,000人 × 20ティック = 毎秒2,000万個。1個40バイトならサーバー全体で約6.4Gbps、受信する1人あたり約6.4Mbps。見える人数を150人に制限すると全体で約1Gbps、1人あたり約1Mbps。
グラフでは 人数・負荷に連動して上昇 · サーバーの送信パケット・バイト、1か所に集まった人数
確認箇所 sar -n DEV 1のtxpck/s・txkB/s(サーバーのNICが毎秒送ったパケット数・KB)を人数のグラフと並べて確認。クラウドのインスタンスではethtool -Sの上限超過カウンター(AWS ENAはbw_out_allowance_exceeded・pps_allowance_exceeded) 該当する場合 集まった人数が増えると送信パケット・バイトが人数よりも急激に(2乗に近く)増え、上限に達した時刻から上限超過カウンターや送信の破棄が増加 該当しない場合 送信量は変わらないのにティック時間だけが増えるなら、視界計算・ゲームロジック側 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 CCP Games 2014: EVE OnlineのHED-GP大規模艦隊戦でのサーバー過負荷
出典5件
ID sp-hotzone · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
エリアごとに1つのスレッドが担当する構造では、1か所に人が集中すると、そのコア1つだけが100%になります。
なぜ 1つのエリア(チャンネル)を1つのスレッドが担当 → すると 人が1か所に集中するとそのコアだけが飽和し、ほかのコアには余裕がある → 画面では そのエリアだけラグが出て、ほかのエリアは問題ない
症状 スローモーション , 入力遅延
要因 ストール
誰に起きるか 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 チャンネルの分散、エリア内部の並列化、人数の上限。
インフラチームの対応 コアごとのCPU使用率を監視・アラートに追加(サーバー全体の平均ではコア1つの飽和が埋もれる)。
数値の目安 16コアのサーバーでコア1つが100%でも、サーバー全体のCPU使用率は約6%に見えます。コアごとの使用率を確認しないと見つけられません。
グラフでは 人数・負荷に連動して上昇 · コアごとのCPU使用率、スレッドごとのCPU
確認箇所 mpstat -P ALL 1でコアごとの使用率を、pidstat -t 1でゲームプロセスのスレッドごとのCPUを確認し、最も忙しいスレッドが担当するゾーンの人数と比較 該当する場合 サーバー全体のCPUは低いのに、スレッド1つ(コア1つ)だけが100%近くに張り付いており、その時刻にそのスレッドが担当するゾーンに人が集中している 該当しない場合 複数のコアが均等に高ければ、サーバー全体の過負荷。1つのコアの%soft(受信処理)だけが高ければ、NIC割り込みの単一コア集中の側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく ほかのエリアが問題ないのは、エリアごとにティックを個別に回している場合の話です。複数のエリアのスレッドが毎ティック互いを待ってから一緒に次のティックへ進む構造なら、最も忙しいエリア1つがサーバー全体のティックを遅らせます。
実際の事例 CCP Games 2014: EVE OnlineのHED-GP大規模艦隊戦でのサーバー過負荷
出典3件
ロック競合 Lock contention
ID sp-lock · 主担当 ゲーム開発チーム・サーバー開発
複数のスレッドが同じデータを使うために1つのロックを待つと、スレッドを増やしても一度に1つずつしか実行されません。
なぜ 取引所・ギルド倉庫のような共有データを、複数のスレッドが同時に使用 → すると ロックを取ったスレッドが終わるまで、ほかのスレッドは待機 → 画面では 特定の機能だけ遅い、ひどい場合は全体のティックが遅延
症状 入力遅延 , フリーズ
要因 ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ロックを細かく分ける、ロック内で行う処理を減らす、メッセージベースの構造(データごとに担当スレッドを決め、ほかのスレッドはメッセージでリクエストだけを送る)。
数値の目安 ロック内の処理が全体の20%なら、スレッドをいくら増やしてもスループットは1スレッドのときの最大5倍、40%なら2.5倍で頭打ちになります。
グラフでは 人数・負荷に連動して上昇 · リクエストの処理時間、スレッドごとのCPU・コンテキストスイッチ
確認箇所 pidstat -w -t 1でスレッドごとの自発的コンテキストスイッチ(cswch/s。資源を待って止まった回数)を、bccのoffcputime -pでスレッドがCPUを離れてどこで待っているか(コールスタックごとの待ち時間)を確認。.NETはdotnet-countersのロック競合数(.NET 9以降はdotnet.monitor.lock_contentions、8以前はMonitor Lock Contention Count) 該当する場合 負荷が増えてもCPU使用率は低いままなのに処理時間が延び、待ち時間の大半がロックを取ろうとするコールスタックに集中し、ロック競合数も一緒に上がる 該当しない場合 CPUが飽和していれば計算量の問題(ティックバジェット超過、シングルスレッドのエリア過負荷)。待っている箇所がDB・ファイルの呼び出しなら、ゲームスレッドの同期呼び出しの側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 複数のスレッドがゲームデータを共同で書き換える構造で起きます。エリア・機能ごとに1つのスレッドが担当し、メッセージだけでやり取りする構造ではロックはほとんど要りませんが、その代わり1つのスレッドに仕事が集中する問題(シングルスレッドのエリア過負荷)に注意が必要です。ゲームスレッドが、遅い保存処理の取っているロックを待つと、そのティック全体が止まります。
実際の事例 Roblox 2021: Robloxの73時間障害:サービスディスカバリ(Consul)クラスターでの競合
出典6件
ID sp-deadlock · 主担当 ゲーム開発チーム・サーバー開発
2つのスレッドが互いに相手の取ったロックを待つと、永遠に止まったままになります。
なぜ スレッドAはロック1を取ったままロック2を、Bはロック2を取ったままロック1を待つ → すると 両方とも永遠に止まり、関連するスレッドも次々に止まる → 画面では サーバー全体が停止し、ウォッチドッグによる再起動で全員が切断
症状 フリーズ , 切断
要因 ストール
誰に起きるか サーバー全体, 特定の機能だけ
いつ ときどきランダムに, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ロックを取る順序のルール、タイムアウト付きのロック、ウォッチドッグと停止した瞬間のスレッドダンプの記録。
グラフでは 接続が一斉に切れる · 接続数、サーバーの送信量
確認箇所 止まっている間に全スレッドのコールスタックを取得。JVMはjstack(デッドロックを自動で検出して表示)、.NETはdotnet-stack、ネイティブのサーバーはgdbのthread apply all bt、またはgcoreでコアファイルを取っておき、再起動した後で分析 該当する場合 2つ以上のスレッドが、互いに相手の取ったロックを待つスタックのまま止まっており、その間プロセスのCPU使用率が0に近い 該当しない場合 止まっている間にスレッド1つがCPUを100%使って回り続けていれば無限ループ。各スレッドがDB・外部の応答を待っていれば、同期呼び出しかスレッドプールの枯渇の側 確認手段 インフラのツールで確認(ゲームコード不要)
出典6件
ゲームスレッドの同期呼び出し Synchronous DB / file I/O on the game loop
ID sp-sync-call · 主担当 ゲーム開発チーム・サーバー開発
ティックの途中でDBの応答やファイルの書き込みを待つと、その時間だけサーバーのゲーム進行全体が止まります。
なぜ ティック内でDBの参照・保存、ログの書き込み、外部APIの呼び出しを待つ → すると DBに100msかかればティックも100ms止まる → 画面では DB・ディスクが遅くなるたびに、フィールド全体が一瞬止まる
症状 フリーズ , カクつき
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 特定の操作をしたとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 遅い処理(DBの参照・保存、ログの書き込み、外部APIの呼び出し)はすべて非同期に回し、結果は次のティックで反映(タイムアウトを設けるだけでは、待っている間はやはり止まる)。
数値の目安 同じデータセンター内のDBとの往復が0.5msでも、1ティックに100回呼べば50msです。20ティックのバジェットをそれだけで使い切ります。
グラフでは 不定期なスパイク · サーバーのティック時間、DBクエリの遅延
確認箇所 ティック時間のグラフとDBクエリの遅延(slow query logなど)・ディスクの遅延を同じ時間軸に並べて確認。ティックのメトリクスがなければ、bccのoffcputime -pでゲームスレッドがどこで待っているか 該当する場合 ティックが跳ねた時刻とDB・ファイルの遅延が跳ねた時刻が重なり、ゲームスレッドの待ち時間がDB応答の受信・ファイル書き込みのコールスタックに集中している 該当しない場合 DB・ディスクの遅延が平常なのにティックが跳ねるなら、GC停止かロック競合の側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
メッセージキューの滞留 Mailbox / job queue backlog
ID sp-queue · 主担当 ゲーム開発チーム・サーバー開発
リクエストが処理速度より速く届いてキューにたまると、後ろのリクエストは数秒後にやっと処理されるか、破棄されます。
なぜ リクエストが処理速度より速く到着 → すると キューが長くなり、上限を超えると破棄 → 画面では スキル・取引の反応が遅れるか、不発になる
症状 入力遅延 , 不発・ロールバック
要因 遅延, パケットロス
誰に起きるか 特定の場所・チャンネル, 特定の機能だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 キュー長の監視、古いリクエストから破棄するポリシー、処理の並列化。
グラフでは 上限で頭打ち · キュー長・最も古いメッセージの経過時間、毎秒の処理数
確認箇所 サーバーが記録するキューごとの長さ、最も古いメッセージの経過時間、毎秒の到着数・処理数・破棄数。コード側のメトリクスがなければ、ss(またはnetstat)でゲームソケットのRecv-Q(カーネルが受信済みで、プロセスがまだ読んでいない量) 該当する場合 到着数が処理数を上回っている間、処理数はある値で頭打ちになり、キュー長・経過時間と破棄数が増え続ける 該当しない場合 キューが短く経過時間も小さいのに反応が遅ければ、回線の遅延かティック自体の遅れの側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
実際の事例 CCP Games 2014: EVE OnlineのHED-GP大規模艦隊戦でのサーバー過負荷
出典4件
タイマーの一斉発火 Synchronized timers
ID sp-timer-burst · 主担当 ゲーム開発チーム・サーバー開発
すべてのモンスターのリスポーン、すべてのバフの期限切れ、毎正時の報酬が同じティックに集中すると、そのティックだけ処理が数十倍重くなります。
なぜ リスポーン・期限切れ・報酬・オートセーブのタイマーが同じ時刻にそろっている → すると その1ティックに普段の数十倍の処理 → 画面では 決まった時刻になるたびに一瞬止まる
症状 フリーズ , カクつき
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 一定の周期で
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 タイマーの時刻をランダムに少しずつ分散、複数のティックに分けて処理。
グラフでは 周期的なスパイク · サーバーのティック時間
確認箇所 ティック時間が跳ねた時刻を集めて間隔を確認(毎正時、5分ごとなど)。同じ時刻に動くリスポーン・バフの期限切れ・報酬・オートセーブのタイマー一覧と照合 該当する場合 ティックが毎回同じ時刻か同じ間隔で跳ね、その時刻に一斉に発火するゲームのタイマー処理がある 該当しない場合 周期はあるが、GCログの停止時刻やサーバーのcron・バックアップの時刻と重なるなら、サーバーGCの全停止か定期実行ジョブの側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典1件
経路探索の急増 Pathfinding storms
ID sp-pathfinding · 主担当 ゲーム開発チーム・サーバー開発
数百体のモンスターが同時にプレイヤーを追いかけて経路を計算すると、CPUを大きく消費します。
なぜ まとめ狩りや大量スポーンで、モンスターが一斉にプレイヤーを追跡 → すると モンスターごとに経路探索を計算 → 画面では その狩場だけスローモーション
症状 スローモーション
要因 ストール
誰に起きるか 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 経路のキャッシュ、計算回数の上限、複数のティックへの分割。
グラフでは 人数・負荷に連動して上昇 · サーバーのティック時間、ゾーンごとのモンスター数
確認箇所 ゾーンごとの、プレイヤーを追跡中のモンスター数とティック時間。個別に数えた値がなければ、perf top -pでゲームプロセスの関数ごとのCPU比率 該当する場合 まとめ狩り・大量スポーンのときにティック時間が延び、経路探索(パスファインディング)の関数がCPU時間の大きな割合を占める 該当しない場合 モンスターは少なくプレイヤーだけが多いときにティックが延びるなら、視界計算かブロードキャストの側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
シリアライズ・圧縮のコスト Serialization / compression cost
ID sp-serialize · 主担当 ゲーム開発チーム・サーバー開発
送るデータをバイト列に変換して圧縮するのにもCPUを使い、人が多いとこのコストが急増します。
なぜ 更新のたびに構造体をバイト列に変換・圧縮 → すると 人数の2乗に比例してコストが増加 → 画面では 送信が遅れて入力遅延
症状 入力遅延
要因 ストール, 遅延
誰に起きるか 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 一度作ったパケットを複数人に再利用、軽量なフォーマット。
グラフでは 人数・負荷に連動して上昇 · サーバーのCPU使用率、パケットを作るスレッドのCPU
確認箇所 perf top -pで、ゲームプロセスのCPU時間に占めるシリアライズ・圧縮・暗号化の関数(zlib・LZ4・OpenSSLのようなライブラリの関数を含む)の比率を、人数が少ないときと集中したときで比較 該当する場合 人数が集中するほどシリアライズ・圧縮・暗号化の関数の比率が大きくなり、パケットを作るスレッドのCPUが先に飽和 該当しない場合 これらの関数の比率が小さければ、視界計算・ゲームロジックの側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく パケットを暗号化する接続(TLS・DTLSなど)なら、暗号化・復号にもCPUを使います。暗号化は接続ごとに個別に行うため、一度作ったパケットを複数人に再利用しても、暗号化のコストは受信者の数だけかかります。AES-GCMのような共通鍵暗号はコア1つで毎秒数GBを処理できるほど速く、普段の比率は小さいですが、一度に暗号化する単位(レコード)のサイズによって速度が大きく変わるため、ゲームのように小さいパケットが多いとバイトあたりのコストが大きくなります。接続ごとに一度行うハンドシェイクでは、サーバーが証明書の鍵で署名し、鍵交換(ECDHE)を計算します。コア1つあたり毎秒の署名は約1,100回(RSA 2048)から1万8千回(ECDSA P-256)、鍵交換は約9千回程度なので、ログインが集中すると負担になります。
出典4件
サーバークラッシュ Server process crash
ID sp-crash · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
未処理のエラーでサーバープロセスが落ちると、そのサーバーにいた全員が同時に切断されます。
なぜ 存在しない対象を参照するエラー(null参照)、不正なデータ、メモリ不足などの致命的なエラー → すると サーバー(またはゾーン)のプロセスが終了 → 画面では 全員が同時に切断、最後の保存以降の進行はロールバックされることがある
症状 切断 , 不発・ロールバック
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ ときどきランダムに, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 クラッシュダンプの分析による原因の修正、こまめな保存。
インフラチームの対応 プロセスの自動再起動、クラッシュダンプの収集・保管環境、サーバーダウン時の即時アラート。
グラフでは 接続が一斉に切れる · 接続数、プロセスの再起動回数
確認箇所 coredumpctl listのコアダンプ記録(時刻、PID、終了シグナル)と、サービスマネージャー(systemd)の異常終了・再起動の記録。WindowsサーバーはWERが残したダンプファイル 該当する場合 接続数が一瞬で0近くまで落ちた時刻に、ゲームサーバープロセスの異常終了とコアダンプがある 該当しない場合 プロセスは動き続けているのに接続が切れたなら、ネットワーク機器・アイドルタイムアウトの側。長く止まった後にウォッチドッグが再起動した記録なら、無限ループ・デッドロックの側 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
スレッドプールの枯渇 Thread pool starvation
ID sp-threadpool · 主担当 ゲーム開発チーム・サーバー開発
処理を担うワーカースレッドがすべて遅い処理に塞がれると、新しいリクエストはいつまでも待たされます。
なぜ ワーカースレッドが外部API・DBの応答待ちで塞がる → すると 新しいリクエストに割り当てるスレッドがない → 画面では ログイン・ショップなど特定の機能が無限ロード
症状 接続不可・無限ロード , 入力遅延 , フリーズ
要因 ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ 人が集中したとき, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 遅い呼び出しにタイムアウト、機能ごとのスレッドプール分離、非同期化。
グラフでは 上限で頭打ち · スレッドプールのスレッド数・キュー長、リクエストの処理時間
確認箇所 .NETはdotnet-counters monitorでスレッドプールのスレッド数とキュー長(.NET 9以降はdotnet.thread_pool.thread.count・dotnet.thread_pool.queue.length、8以前はThreadPool Thread Count・ThreadPool Queue Length)を確認し、dotnet-stackでワーカースレッドがどこで待っているかを確認。JVM・ネイティブのサーバーはスレッドダンプで同じことを確認 該当する場合 CPU使用率は100%よりかなり低いのに、スレッド数がゆっくり増え続けるか上限に張り付いており、キューがたまり、ワーカーの大半が同じ外部呼び出し(DB・HTTP)の応答を待っている 該当しない場合 キューが空なのに遅ければ呼び出し先そのものが遅いので、カスケード障害・外部サービスへの依存の側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく パケットの受信とゲームロジックが同じワーカースレッドプールを共有する構造では、数個の遅い処理がワーカーをすべて占有した瞬間に、サーバー全体のパケット処理が止まります。
実際の事例 Riot Games 2021: League of Legends EUWの5時間障害:補助的なDB一つでサーバー全体が停止
出典5件 Debug ThreadPool Starvation Microsoft プールに空きスレッドがなく新しい処理が待たされると応答が遅くなる、スレッドを占有するブロッキングコードが原因。dotnet-countersでCPUは100%よりかなり低いのにdotnet.thread_pool.thread.countがゆっくり増え続けるなら枯渇のサイン(dotnet.thread_pool.queue.lengthも大きいことが多い)、dotnet-stackでスレッドが待っている箇所を確認 Avoiding insurmountable queue backlogs AWS 同時処理数 = 到着率 × 遅延(リトルの法則)。毎秒100件で遅延が100msから10秒に延びると、スレッドが10本から1,000本に増えてプールが枯渇 Bulkhead Pattern Microsoft Azure 呼び出し先ごとにコネクションプール・スレッドプールを分けておけば、1つの呼び出し先の障害はそのプールだけを塞ぐ .NET runtime metrics .NET dotnet.thread_pool.thread.count(スレッドプールのスレッド数)・dotnet.thread_pool.queue.length(待機中の処理数)は.NET 9から Well-known EventCounters in .NET Microsoft .NET 8以前のThreadPool Thread Count(threadpool-thread-count)・ThreadPool Queue Length(threadpool-queue-length)
無限ループ・ロジックの暴走 Infinite loop / runaway logic
ID sp-infinite-loop · 主担当 ゲーム開発チーム・サーバー開発
バグで1ティックが終わらないとサーバーが止まり、ウォッチドッグが強制的に再起動します。
なぜ 誤った条件でループが終わらない、または再帰が暴走 → すると ティックが終わらずサーバーが停止 → 画面では フリーズの後、全員が切断
症状 フリーズ , 切断
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 特定の操作をしたとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ループ回数の上限、ウォッチドッグ、問題の入力を再現するテスト。
グラフでは 接続が一斉に切れる · 接続数、スレッドごとのCPU
確認箇所 止まっている間にpidstat -t 1でスレッドごとのCPUを確認し、100%で回っているスレッドがどの関数で回っているかをperf top -t(スレッドID)かgdbで確認。すでに再起動していれば、ウォッチドッグのタイムアウト記録(systemdのWatchdogSec、KubernetesのLiveness Probe失敗) 該当する場合 サーバーが止まっている間、ゲームスレッド1つがCPU使用率100%に張り付いており、スタックが同じ関数・ループの中で回り続けている 該当しない場合 止まっている間CPUが0に近ければ、デッドロックか外部の応答待ちの側 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID sp-hot-entity · 主担当 ゲーム開発チーム・サーバー開発
数百人が1体のボスを同時に攻撃すると、そのボス1体の計算が1か所に集中し、ヒット情報が見ている全員に送信されます。
なぜ 数百人が1体のボスにスキル・バフ・デバフを絶え間なく使用 → すると ボスのHP・ヘイトリスト・デバフの計算が1か所に集中し、ヒットのたびにダメージ数値・エフェクトのパケットを見ている全員に送信 → 画面では スキルの反映が遅れ、ダメージ数値がまとめて表示される、ボスの周辺だけスローモーション
症状 入力遅延 , 早送り , スローモーション
要因 ストール, 遅延
誰に起きるか 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ほかのプレイヤーのダメージ数値・エフェクトはまとめるか省略、1つの対象にかかるデバフ数の上限、ヒット処理を複数のティックに分割。
数値の目安 800人が毎秒2回ずつ攻撃すれば、毎秒1,600回のヒットです。これを見ている800人全員に通知すると、毎秒128万個のメッセージになります。
グラフでは 人数・負荷に連動して上昇 · サーバーのティック時間、送信メッセージ数
確認箇所 ボス戦の時間帯のティック時間と送信パケット数を、ボス周辺の人数と並べて確認し、可能なら対象ごとの毎秒のイベント(ヒット・バフ・デバフ)数 該当する場合 ボス周辺の人数が増えるとティック時間と送信量が急激に増え、ボス1体の毎秒のイベント数がほかの対象より数十倍多い 該当しない場合 ボスと関係なく1か所に集まるだけで同じように遅くなるなら、視界計算かブロードキャストの急増の側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典1件
密集エリア進入時のスポーン集中 Spawn burst when entering a crowd
ID sp-spawn-burst · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
人でいっぱいの街にテレポートすると、サーバーは新たに見えるようになった数百人の外見・装備・状態を一度に送らなければなりません。
なぜ テレポート・ログイン・チャンネル移動で、混雑した場所に突然現れる → すると 数百人分の全情報を一度に作って送り、自分のPCも一度に読み込む → 画面では 到着直後に一瞬止まる、キャラクターが遅れて1体ずつ現れ、入力の反応が遅い
症状 フリーズ , 入力遅延 , 早送り
要因 ストール, 遅延
誰に起きるか 自分だけ, 特定の場所・チャンネル
いつ 移動中・マップ切り替え時, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:近い順に複数のティックに分けて送信、外見情報のキャッシュ。クライアント:ロード画面の間に先に受信、受け取ったキャラクターを複数フレームに分けて生成。
数値の目安 1人分の外見・装備・バフの情報が300バイトなら、500人で約150KBです。普段の1ティックの送信量(数KB)の数十倍が一瞬に集中します。
グラフでは 接続直後・メンテ明けに急増 · 接続ごとの送信バイト数、クライアントのフレームタイム
確認箇所 混雑した場所に到着した直後の数秒間に、その接続へ送ったバイト数・パケット数(サーバーログ)と、クライアントのフレームタイム(ネットグラフ・クライアントログ) 該当する場合 到着直後にその接続の送信量が普段の1ティックの数十倍に跳ね上がってから落ち着き、同じ瞬間にクライアントのフレームタイムも跳ねる 該当しない場合 人の少ない場所へ移動しても同じように止まるなら、ゾーン移動(サーバー間の引き継ぎ)かクライアントのロードの側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
ID sp-entity-buildup · 主担当 ゲーム開発チーム・サーバー開発
消えるはずの地面のアイテム、召喚物、終わったタイマーが片付けられずにたまると、サーバーを長く稼働させるほど毎ティックの処理が増えます。
なぜ 地面のアイテム・召喚物・期限切れのタイマー・空のパーティ情報が、本来のタイミングで削除されない → すると ティックごとに走査するリストが日ごとに長くなる → 画面では メンテ明けは問題ないが、数日たつとそのサーバー・エリアだけ次第に重くなる
症状 スローモーション , カクつき , 入力遅延
要因 ストール
誰に起きるか サーバー全体, 特定の場所・チャンネル
いつ 長時間稼働するほど
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 エリアごとのオブジェクト数をメトリクスとして記録して傾向を確認、オブジェクトごとの寿命と個数の上限、定期的なクリーンアップ。
数値の目安 ティックごとにすべてのオブジェクトを1回ずつ走査するサーバーなら、オブジェクト数が2倍になると、その部分のティック時間も2倍になります。
グラフでは 徐々に上昇して急落 · ゾーンごとのオブジェクト数、サーバーのティック時間
確認箇所 ゾーン・サーバーごとのオブジェクト数(地面のアイテム・召喚物・タイマー)とティック時間を、メンテナンスの周期より長い期間(数週間)で確認 該当する場合 メンテ明けに低い値から始まったオブジェクト数とティック時間が日ごとに上がり、メンテナンス・再起動のたびにがくんと下がることを繰り返し、その間メモリには余裕がある 該当しない場合 ティックは変わらないのにメモリだけが上がり続けるなら、メモリリークの側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく メモリリークと同じく長く稼働するほど悪化しますが、メモリには余裕があるのにティック時間だけが延びる点が異なります。オブジェクト数のグラフがメンテナンスの周期ごとにのこぎり状になっていれば、このケースです。
出典2件
ID sp-patch-traffic · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ
新しいコンテンツ・エフェクト・同期項目がパケットのサイズと頻度を増やすと、問題なく動いていたサーバーがアップデート後からMTU・帯域幅・パケット数の上限に引っかかります。
なぜ アップデートで新しいスキルエフェクト・同期項目・アイテム情報が増え、パケットが大きくなるか頻繁になる → すると 大きなパケットはMTUを超えてフラグメント化され、増えた分は帯域幅・クラウドのPPS上限・送信バッファに引っかかる → 画面では アップデート直後から、混雑した場所でワープ・スキル不発・入力遅延。インフラは何も変えていないのにパケットロスが増える
症状 ワープ , 不発・ロールバック , 入力遅延
要因 パケットロス, 遅延
誰に起きるか サーバー全体, 特定の場所・チャンネル, 特定の地域・ISP
いつ 人が集中したとき, 夜のピーク時間帯, 常に
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 パケットを1,200バイト以下に自前で分割、新しい同期項目は変更分だけを送り、距離・重要度に応じて頻度を下げる、デプロイ前にテストサーバーでユーザーあたりの毎秒パケット数・バイト数と最大パケットサイズを前のビルドと比較、トラフィックのメトリクスにビルドバージョンを記録。
インフラチームの対応 サーバー機器・OS:デプロイ時刻をグラフに表示し、ユーザーあたりの毎秒パケット数・バイト数と平均パケットサイズをデプロイ前後で比較、インスタンスの上限超過カウンターにアラート、必要ならより大きなインスタンス。ネットワーク:ファイアウォール・ロードバランサー・DDoS対策機器の処理上限と、フラグメントを遮断していないかを点検。
数値の目安 UDPパケットは1,200バイト以下なら安全で、インターネットの経路MTUは通常1,500バイト、トンネルを通るとさらに小さくなります(GREトンネルなら1,476バイト)。経路MTUを超えたパケットはフラグメント化されるか破棄され、フラグメント化されたパケットはフラグメントを1つ失うだけで全体が失われます。ユーザーあたりの毎秒パケット数が20%増えればサーバー全体でも20%増えるため、上限近くで使っていたインスタンスはすぐにあふれます。
グラフでは ある時点から階段状に上昇 · ユーザーあたりの毎秒パケット数・バイト数、平均パケットサイズ
確認箇所 デプロイ時刻の前後で、サーバーのNICの毎秒パケット数・バイト数(sar -n DEVのrxpck/s・txpck/s・rxkB/s・txkB/s、EC2ではNetworkPacketsOut・NetworkOut)を同時接続数で割って比較。平均パケットサイズはバイト数 ÷ パケット数、サイズの分布はパケットキャプチャをWiresharkのPacket Lengths統計で確認 該当する場合 デプロイ直後からユーザーあたりのパケット数・バイト数や平均パケットサイズが一段上がったまま推移し、同じ時刻からサーバーが作ったフラグメント数(sar -n IPのfragcrt/s)やインスタンスの上限超過カウンター(AWS ENAのpps_allowance_exceeded・bw_out_allowance_exceeded)が増える 該当しない場合 トラフィックパターンはデプロイ前後で同じなのに遅延・パケットロスだけが増えたなら、同じ時刻のインフラ変更(設定、経路、機器、OS・カーネルのアップデート)を確認 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 「アップデート前は問題なかった」という報告が来たら、インフラの変更と合わせて最初に確認すべきゲーム側の原因です。パッチノートにネットワークの変更がなくても、新しいエフェクトや同期項目が1つ増えるだけで、混雑した場所では数百人分に掛け算されます。増えたトラフィックが実際に引っかかる箇所は、「UDPパケットのIPフラグメンテーション」「クラウドのPPS上限超過」「NIC帯域幅の飽和」「カーネルのソケットバッファ不足」「中間機器の処理上限超過(ファイアウォール・IPS・DDoS対策)」の各項目で扱います。この項目は、その上限に達する出発点がゲームのアップデートだった場合なので、上限を引き上げる前に、アップデートで増えたトラフィックをまず減らします。同じ時刻にOS・カーネルもアップデートしていたなら、ユーザーあたりのトラフィックが変わったかどうかで「OS・カーネル・ドライバー・ファームウェアのアップデート後の性能変化」と切り分けます。
出典7件
L10 メモリ
原因9件 · メインページの章
サーバーGCの全停止 Stop-the-world GC pause
ID mem-gc · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
Java・C#のサーバーがガベージを回収するために全スレッドを止めている間(stop-the-world)、サーバー全体が止まります。
なぜ ヒープが埋まってGCが始まる → すると 全ゲームスレッドを止めて回収(生存データが多いほど長引く) → 画面では サーバー上の全員が同時にフリーズし、その後早送り
症状 フリーズ , 早送り
要因 ストール
誰に起きるか サーバー全体
いつ 一定の周期で, 長時間稼働するほど
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 停止時間の短いGC(ZGC、Shenandoah、目標時間を短くしたG1)を起動オプションで明示的に指定、アロケーションの削減、ヒープサイズの調整。
インフラチームの対応 ヒープを十分に確保できるメモリ量のインスタンス、コンテナにはCPUを2個以上・メモリを約1.8GB以上割り当て(JDK 26以前はそれより小さいとSerial GCがデフォルトで選ばれる)、GC停止時間の監視。
数値の目安 新しいオブジェクト(Young領域)だけを回収するMinor GCは数〜数十ms。生存データが数GBあるヒープ全体を回収するFull GCは1秒を超えることもあります。ZGCはヒープサイズにほとんど関係なく1ms未満で、Shenandoahも停止時間がヒープサイズに比例しないため短く済みます。
グラフでは 周期的なスパイク · サーバーのティック時間、GC停止時間
確認箇所 GCログを有効にし、停止した時刻と長さをサーバーのティック時間グラフに重ねて確認。Javaは起動オプション-Xlog:gc*(JDK 8以前は-XX:+PrintGCDetails)のPause行、.NETはdotnet-countersのGC停止メトリクス(.NET 9以降はdotnet.gc.pause.time、8以前は% Time in GC since last GC)、GoはGODEBUG=gctrace=1がGCごとに出力する行を確認 該当する場合 ティックが跳ねた時刻とGC停止の時刻が重なり、停止の長さが跳ねた長さとほぼ同じ。サーバーのすべてのゾーン・チャンネルが同じ瞬間に跳ねる 該当しない場合 GCログに長い停止がないのにティックが跳ねるなら、ロック・同期呼び出し・ディスク書き込みなど別の原因。1つのゾーンだけ跳ねるなら、スクリプトエンジンのGC(mem-script-gc)かそのゾーンの負荷 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく JavaのG1は1回あたりの停止目標がデフォルトで200msなので、20ティックのサーバーでは4ティック分に相当します。コンテナにCPUを2個未満、またはメモリを約1.8GB未満しか割り当てないと、JDK 26以前のJavaは単一スレッドで回収するSerial GCをデフォルトのGCとして選び、停止がはるかに長くなります。C#(.NET)のサーバーは通常サーバーGCとバックグラウンドGCを有効にしますが、新しいオブジェクトを入れる第0・第1世代(Gen0・1)の回収と、コンパクション(圧縮)を伴うFull GCは依然として全スレッドを止めます。Goは停止が通常1ms未満ですが、アロケーションが多いとメモリを要求した側がGC作業を分担しなければならず、ティックが遅くなります。どの方式でも、アロケーションが回収より速ければ最終的にゲームスレッドが止まります。G1はFull GCに移行し、ZGCはメモリを要求したスレッドを回収が終わるまで止めます。
実際の事例 Riot Games 2021: League of Legends EUWの5時間障害:補助的なDB一つでサーバー全体が停止
出典10件
ID mem-script-gc · 主担当 ゲーム開発チーム・サーバー開発
C++のサーバーでも、クエスト・AI・スキルをLuaなどのスクリプトで動かしていると、スクリプトエンジンのGCが走っている間そのゾーンが止まります。
なぜ ゾーンごとにスクリプトエンジンがクエスト・AI・イベントを実行し、一時オブジェクトを大量に生成 → すると スクリプトエンジンのGCが一度に大量に回収すると、そのゾーンのティックが止まる → 画面では 特定のゾーン・特定のイベント中だけ周期的に一瞬止まる
症状 カクつき , フリーズ
要因 ストール
誰に起きるか 特定の場所・チャンネル
いつ 人が集中したとき, 一定の周期で
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 インクリメンタル・世代別GCの設定、ティックごとに少しずつGCを進める、スクリプトの一時オブジェクトの削減。
数値の目安 スクリプトのヒープが数百MBまで膨らむと、一度にまとめて行う回収(インクリメンタル回収を無効にした場合や、世代別モードでの全体回収)に数十〜数百msかかることもあります。
グラフでは 周期的なスパイク · ゾーン別のティック時間、スクリプトエンジンのメモリ
確認箇所 ゾーン別のティック時間と、そのゾーンのスクリプトエンジンのメモリ使用量(Luaはcollectgarbage("count"))をティックごとに記録し、1つのグラフに重ねて確認 該当する場合 スクリプトのメモリがガクッと下がる瞬間(一度にまとめて回収)とそのゾーンのティックのスパイクが重なり、他のゾーンは正常 該当しない場合 スクリプトのメモリに変化がないまま跳ねるなら、そのゾーンの負荷かロック。サーバーのすべてのゾーンが同時に跳ねるなら、サーバーのGC(mem-gc)かスワップ(mem-swap) 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典1件 Lua 5.4 Reference Manual Lua.org インクリメンタルモードは回収を小さなステップに分けて実行の合間に挟み込み(ステップを大きく取ると全停止)、世代別モードのmajor回収はすべてのオブジェクトをたどる全停止、collectgarbage("count")はLuaが使っているメモリの総量(KB)
ID mem-alloc · 主担当 ゲーム開発チーム・サーバー開発
イベント中に一時オブジェクトを大量に生成すると、GCが普段よりはるかに頻繁に走ります。
なぜ アイテムドロップ・戦闘ログ・イベント報酬で一時オブジェクトが急増 → すると GCが数倍の頻度で走り、まだ破棄されていなかったオブジェクトがOld領域に移ってFull GCも早まる → 画面では イベント時だけ周期的に一瞬止まる
症状 カクつき , フリーズ
要因 ストール
誰に起きるか サーバー全体, 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 オブジェクトプール、バッファの再利用、アロケーションのプロファイリング。
グラフでは 人数・負荷に連動して上昇 · GC回数、アロケーション速度
確認箇所 GCログ(Java -Xlog:gc、Go GODEBUG=gctrace=1)で1分あたりのGC回数を数え、.NETはdotnet-countersのアロケーション量とGC回数(.NET 9以降はdotnet.gc.heap.total_allocated・dotnet.gc.collections、8以前はAllocation Rate・Gen 0 GC Count)を確認。同時接続数・イベントの時刻と重ねて確認 該当する場合 イベントが始まると、アロケーション速度とGC回数が人数の増加より急激に増え、短い停止が頻発。イベントが終わると元に戻る 該当しない場合 GC回数は変わらないのに1回の停止が長くなるなら、生存データが増えている(mem-gc-thrash、mem-leak) 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID mem-leak · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
解放されないメモリが少しずつたまり、数日後にGCの多発・スワップ・強制終了につながります。
なぜ ログアウトしたキャラクターの情報・イベントハンドラーが解放されない → すると 数日かけて空きメモリが減っていく → 画面では メンテ明けは正常、日を追うごとにラグが増え、最後はサーバーダウン
症状 スローモーション , フリーズ , 切断
要因 ストール
誰に起きるか サーバー全体
いつ 長時間稼働するほど, 夜のピーク時間帯
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 ヒープダンプの解析、長時間の負荷テスト。
インフラチームの対応 プロセスごとのメモリ使用量の推移の監視とアラート。
グラフでは 徐々に上昇 · プロセスのメモリ(RSS)、GC直後のヒープ
確認箇所 ゲームサーバープロセスのメモリ(pidstat -rのRSS)を数日単位で確認し、GCを使うサーバーはGC直後に残ったヒープを確認。Javaは-Xlog:gcの行に出るGC前・後の使用量のうちGC後の値、.NETはdotnet-countersのGC後のヒープサイズ(.NET 9以降はdotnet.gc.last_collection.heap.size、8以前はGC Heap Size) 該当する場合 GC直後に残るヒープ(ベースライン)が再起動後に日ごとに上がり、人数の少ない早朝にも下がらない 該当しない場合 ヒープのベースラインは横ばいなのにRSSだけ上がるなら、断片化(mem-fragment)かネイティブメモリ側。人数に連動して上下するなら正常な使用量 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 定期メンテで毎週再起動していると、リークが隠れて長い間見つかりません。メンテが一度延期されたときや、イベントで人数が増えたときに突然表面化することがよくあります。
出典5件
ID mem-gc-thrash · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
生存データがヒープの上限に近づくと、GCが走っても回収できるものがほとんどなく、GCが休みなく繰り返されます。
なぜ イベントでの人数増加やリークで、生存データがヒープの上限近くまで埋まる → すると GCがわずかしか回収できず、すぐにまたFull GC、CPUの大半をGCが使う → 画面では サーバー全体が数分間スローモーション・フリーズを繰り返し、メモリ不足で終了
症状 スローモーション , フリーズ , 切断
要因 ストール
誰に起きるか サーバー全体
いつ 夜のピーク時間帯, 人が集中したとき, 長時間稼働するほど
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 ヒープをピーク時の生存データより余裕をもって(通常2倍以上)設定、長く参照し続けるデータ・リークの削減。
インフラチームの対応 GC時間比率のアラート、粘らずに早めに再起動、ヒープを増やせるようメモリに余裕のあるインスタンス。
数値の目安 実行時間の10%を超えてGCに使っていれば、一般に危険信号とみなします。Javaの一部のGCは、時間の98%をGCに費やしてもほとんど回収できないとメモリ不足のエラーを出します。
グラフでは 上限で頭打ち · GC直後のヒープ、GC時間比率
確認箇所 GC直後に残ったヒープが最大ヒープにどれだけ近いかと、GCに使った時間の比率を確認。Javaは-Xlog:gcの行の「GC後(ヒープサイズ)」とPause Full行の頻度、.NETはdotnet-counters(.NET 8以前は% Time in GC since last GC、.NET 9以降はdotnet.gc.pause.timeの増加量)、GoはGODEBUG=gctrace=1の行と行の間隔を確認 該当する場合 GC直後もヒープが最大値近くまで残り、Full GCが立て続けに走り、GC時間比率が普段より大きく(通常10%超)上がる。その間サーバー全体のティックがそろって遅くなる 該当しない場合 GC直後のヒープに余裕があるのに停止だけが長いなら、GC方式・設定側(mem-gc) 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
スワップ Swapping
ID mem-swap · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
メモリが足りずOSが一部をディスクに退避させると、そのメモリを使うたびに1,000倍以上遅いディスクを待つことになります。
なぜ 使用メモリが物理RAMを超える → すると OSが一部をディスクに退避させ、必要なときに読み戻す → 画面では ティックが数百msに跳ね上がり、サーバーの全ユーザーがスローモーション・フリーズ
症状 スローモーション , フリーズ
要因 ストール
誰に起きるか サーバー全体
いつ 長時間稼働するほど, 夜のピーク時間帯
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 プロセスのメモリ使用量に上限(ヒープサイズなど)を設け、リークを点検。
インフラチームの対応 ゲームサーバーはスワップを使わない設定、メモリのアラートで対応、スワップを無効にするとメモリ不足の瞬間に強制終了(OOM)するため、ピーク使用量より余裕のあるRAMを確保。
数値の目安 RAMの読み出し約100ns、SSDからの読み戻し約100µs(1,000倍)、ネットワーク越しのクラウドディスクは約1ms(1万倍)、HDDは10ms(10万倍)。
グラフでは 徐々に上昇 · スワップ使用量、スワップイン・アウト
確認箇所 vmstat 1のsi・so列(1秒あたりにスワップから読み込んだ量・スワップへ書き出した量)、/proc/pressure/memoryのsome・full(メモリ待ちで止まった時間の割合)、ゲームサーバープロセスのpidstat -r majflt/s(ディスクから読み込む必要があったページフォルト)をティック時間と重ねて確認 該当する場合 ラグの時刻にsiが0より大きく、ゲームサーバーのmajflt/sとmemoryのfull値が一緒に上がる 該当しない場合 si・soが0で、メモリプレッシャー(PSI)も0付近ならスワップは原因ではない。スワップがないのにmajflt/sとPSIが上がるなら、メモリが尽きてコードページを読み直している状態なので、メモリの確保が先 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく GCを使うサーバーは回収時にヒープのあちこちを読むため、ヒープの一部がスワップされただけでも1回のGCが数秒〜数十秒に延びることがあります。スワップを無効にすると、スワップで遅くなる段階を経ずに強制終了(OOM)に進むので、空きメモリを先に確保しておく必要があります。スワップがなくても、メモリが底をつきかけるとOSが実行ファイルのコードページまでメモリから追い出しては読み直すため、強制終了の前にしばらくサーバー全体がひどく遅くなることがあります。
出典8件
キャッシュミス CPU cache misses
ID mem-cache-miss · 主担当 ゲーム開発チーム・サーバー開発
データがメモリのあちこちに散らばっていると、CPUが毎回遅いRAMまで取りに行って待つことになります。
なぜ オブジェクトがポインターでつながって散らばり、順不同にアクセス → すると CPUキャッシュにないので毎回RAMから読む(100倍前後遅い) → 画面では 同じ処理でもティックのコストが数倍、ひどいとスローモーション
症状 スローモーション
要因 ストール
誰に起きるか サーバー全体
いつ 常に, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 よく一緒に使うデータを連続して配置(データ指向設計)。
グラフでは 最初から常に高い · ティック時間、CPU使用率
確認箇所 ゲームサーバープロセスにperf stat -d -p PIDをかけて、サイクルあたりの命令数(insn per cycle)とL1・LLCのキャッシュミスを計測し、ティック時間・CPU使用率と合わせて確認 該当する場合 CPUはずっと忙しいのにinsn per cycleが低く、LLCミスが多い。データ配置を変えたビルドで、同じ人数でのティック時間が大きく減れば確定 該当しない場合 CPU使用率が低いのにティックが遅いなら、ロック・I/O待ちのようにCPUの外で待っている原因 確認手段 インフラのツールで確認(ゲームコード不要)
出典2件
メモリの断片化 Heap fragmentation
ID mem-fragment · 主担当 ゲーム開発チーム・サーバー開発
アロケーションと解放を繰り返して空き領域が細かく分断されると、実際に使っている量よりはるかに多くのメモリを占有するようになります。
なぜ サイズがまちまちのメモリを、複数のスレッドが長期間アロケーション・解放 → すると 空き領域が細かく散らばってOSに返せず、使用量がリークのように増え続ける → 画面では 長く稼働するほどスワップ・メモリ不足で遅くなり、最後は強制終了
症状 スローモーション , 切断
要因 ストール
誰に起きるか サーバー全体
いつ 長時間稼働するほど
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 サイズ別のメモリプール、断片化に強いアロケーター(jemalloc、mimallocなど)。
グラフでは 徐々に上昇 · プロセスのメモリ(RSS)
確認箇所 同じビルドのサーバーを2つ起動し、片方だけ環境変数MALLOC_ARENA_MAXでglibcのアリーナ数を減らすか、jemallocなど別のアロケーターに替えて、数日間pidstat -rのRSSを比較 該当する場合 人数・オブジェクト数はほぼ同じなのに、変更したサーバーだけRSSの増加が止まるか大きく減る 該当しない場合 アロケーターを替えても同じように上がるなら、解放されないメモリ(mem-leak) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく リークと同じ形になるため、ヒープを解析してもリーク箇所は見つかりません。Linuxの標準アロケーター(glibc)はスレッドの多いサーバーで特にひどく、アロケーターを替えるだけで使用量が大きく減ることもあります。
出典3件
ID mem-numa · 主担当 インフラチーム・サーバーインフラ
CPUが2つあるサーバーで、反対側のCPUにつながったメモリを使うとアクセスが遅くなります。
なぜ スレッドとメモリが別々のCPUソケットに配置される → すると メモリアクセスが遅くなる(機器によって1.5〜2倍) → 画面では 同じスペックなのにプロセスごとに性能差
症状 スローモーション
要因 ストール
誰に起きるか サーバー全体
いつ 常に
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 プロセス・メモリを1つのソケットに固定(numactl)、ソケットが2つならソケットごとにゲームサーバープロセスを分けて配置。
グラフでは 一部だけ高い · プロセスごとのティック時間、ノードごとのメモリ
確認箇所 numastat -p PIDでゲームサーバープロセスのメモリがどのNUMAノードにあるか、numastatのnuma_miss・other_nodeが増えているかを確認し、そのプロセスが動いているCPUのノードと比較 該当する場合 遅いプロセスだけ、メモリの大半が自分の動いているCPUとは別のノードにあり、numactlでCPU・メモリを1つのノードに固定して再起動すると差がなくなる 該当しない場合 速いプロセスとノード配置が同じなのに遅いなら、ノイジーネイバー、CPUスロットリング、そのプロセスの負荷など別の原因 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
L11 ディスク
原因9件 · メインページの章
同期ログ書き込み Synchronous logging
ID dk-sync-log · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲームスレッドがログを1行書くたびにディスクへの書き込み完了を待っていると、ディスクが忙しいときにゲームの進行も一緒に止まります。
なぜ 戦闘・取引ログをゲームスレッドから直接ファイルに書く → すると 確実な書き込み(fsync)を要求したり、OSの書き込みバッファ(ページキャッシュ)が上限に達したりすると、ディスクが忙しいときに1回の書き込みが数十ms → 画面では ログの多い戦闘で一瞬止まる
症状 カクつき , フリーズ
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 非同期ロギング(メモリバッファ + 別スレッド)、ログ量の削減、ゲームスレッドではfsyncしない。
インフラチームの対応 ログのローテーション・圧縮はI/O優先度を下げて実行、ログはデータとは別のディスクに、ディスク書き込み遅延の監視。
グラフでは 不定期なスパイク · サーバーのティック時間、ディスク書き込み遅延
確認箇所 iostat -x 1のw_await・aqu-szをティック時間と重ねて確認し、perf trace -p PID --duration 10でゲームサーバー内の10msを超えたwrite・fsync呼び出しとそのスレッドを探す 該当する場合 ティックが跳ねた時刻に、ゲームスレッドのwrite・fsync呼び出しが数十msかかり、その瞬間ディスク書き込み遅延も跳ね上がる。ログのローテーション・圧縮の時刻と重なることが多い 該当しない場合 ゲームスレッドに時間のかかったシステムコールがないのにティックが跳ねるなら、GC・ロック・ティックバジェット超過など別の原因。ログ専用スレッドだけが長くかかっているなら、ゲームの進行には影響しない 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 通常、OSは書き込みをまずメモリ(ページキャッシュ)で受け取り、あとからディスクに書き出すので、ログ1行の書き込みはたいていすぐに終わります。止まるのは、fsyncで確実な書き込みを要求したとき、たまった書き込みが上限を超えてOSが書き込みの呼び出しをブロックしたとき、ログファイルをローテーションしたり圧縮したりするときです。そのため、普段は問題ないのに、ディスクが忙しい瞬間にだけ跳ねます。
出典5件
ID dk-fsync · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・DBインフラ
データを「確実に」ディスクに書き込むよう要求すると、ディスクによっては1回に0.1ms〜数十msかかり、要求が集中するとキューが長くなります。
なぜ 定期保存・ログアウトラッシュで確実な書き込みの要求が集中 → すると ディスクのキューが長くなる → 画面では 保存のタイミングごとにラグ、ログアウト・チャンネル移動の遅延
症状 カクつき , 入力遅延
要因 ストール, 遅延
誰に起きるか サーバー全体
いつ 一定の周期で, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・DBインフラ
ゲーム開発チームの対応 保存をまとめて一度に(複数の保存を1回のfsyncで)、保存時刻の分散。
インフラチームの対応 サーバー機器・OS:電源保護機能のあるサーバー向けSSD、ディスクのキュー長・fsync遅延の監視。DBサーバー:保存先がDBなら、DBのログディスクも同様のSSDに、コミット遅延の監視。
数値の目安 1回にかかる時間は機器によって異なりますが、おおよそサーバー向けSSD(電源保護機能付き)で0.1ms、一般的なSSDで1〜数ms、クラウドディスクで1〜2ms、HDDで10ms以上です。1つのスレッドが1回ずつ待つと、HDDでは1秒に100回もこなせません。
グラフでは 周期的なスパイク · ディスクのキュー長、フラッシュ・書き込み遅延
確認箇所 iostat -x 1のf/s・f_await(ディスクが処理したフラッシュの数とかかった時間)、w/s・aqu-sz・w_awaitを定期保存・ログアウトの時刻と重ねて確認。古いsysstatはaqu-szをavgqu-szと表示する。クラウドディスクはEBSのVolumeQueueLength・VolumeAvgWriteLatencyを確認 該当する場合 保存時刻・ログアウトラッシュのたびにフラッシュ数とキュー長が一緒に跳ね上がり、w_await・f_awaitが普段の数倍になる。そのとき保存・チャンネル移動が遅れる 該当しない場合 保存・ログアウトと関係ない時刻にキューが跳ね上がるなら、バックアップ・圧縮(dk-backup)かIOPS上限(dk-iops)。フラッシュ数は変わらないのに遅くなるなら、バーストクレジットの枯渇(dk-burst)側 確認手段 インフラのツールで確認(ゲームコード不要)
出典6件
ID dk-burst · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ
一部のクラウドディスクや小さなサーバースペックには、一時的にベースラインより速く使えるバーストクレジットがあります。忙しい時間が長引いてクレジットが底をつくと、速度が急に落ちます。
なぜ ベースライン性能を超えて長時間使用 → すると バーストクレジットが底をつき、ベースライン性能まで急落 → 画面では 毎晩、数時間たったころからラグが出始める
症状 カクつき , スローモーション , 入力遅延
要因 ストール, 遅延
誰に起きるか サーバー全体
いつ 夜のピーク時間帯, 長時間稼働するほど
担当 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ
インフラチームの対応 サーバー機器・OS:性能保証型のディスク(gp3、IOPS指定型)、クレジット残高のアラート、インスタンスのディスク帯域幅のバースト上限とCPUクレジットも合わせて確認。DBサーバー:マネージドDBを含むDBのディスクも性能保証型に変更し、クレジット残高のアラート。
数値の目安 AWSのgp2 100GBディスクは通常300、バースト時3,000 IOPSで、クレジットが満タンなら約30分持ちます。gp3はクレジットなしで常に3,000です。Azureの小さなPremium SSDも、クレジットで最大30分バーストします。
グラフでは 上限で頭打ち · IOPS、バーストクレジット残高
確認箇所 CloudWatchのEBS BurstBalance(gp2・st1・sc1)、インスタンスのEBSIOBalance%・EBSByteBalance%(バーストする一部のインスタンス)、バースト可能インスタンスのCPUCreditBalanceを確認。AzureはData Disk Used Burst IO Credits Percentageなど、バーストクレジット使用率のメトリクスを確認 該当する場合 残高が0近くまで下がった時刻から、IOPS(VolumeReadOps・VolumeWriteOps)がベースライン性能で頭打ちになり、VolumeQueueLengthとラグが一緒に増える。ピークが数時間続いた後に始まる 該当しない場合 残高がどれも十分なのにIOPSが頭打ちなら、ボリューム・インスタンスの固定上限(dk-iops) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく ディスク自体に問題がなくても、小さな仮想サーバーはインスタンスのディスク帯域幅そのものにバースト上限(1日最低30分など)があり、同じ形になります。CPUクレジットを使う低価格のサーバーも、クレジットが底をつくとベースライン性能まで遅くなります。
出典7件
IOPS上限・キューの飽和 IOPS limit / queue saturation
ID dk-iops · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・DBインフラ
ディスクが1秒間に処理できる要求数を超えると、キューが長くなって遅延が急増します。
なぜ 読み書きの要求がディスクの処理能力に近づく → すると キューが長くなる(たいてい利用率90%以上で急増) → 画面では 保存・ロードの遅延、同期呼び出しならフリーズ
症状 入力遅延 , フリーズ
要因 遅延, ストール
誰に起きるか サーバー全体
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・DBインフラ
ゲーム開発チームの対応 要求をまとめる、よく読むデータはキャッシュ、ゲームスレッドでディスクを待たないよう非同期に。
インフラチームの対応 サーバー機器・OS:より高速なディスク、インスタンスタイプごとのディスク帯域幅・IOPS上限の確認、ディスク利用率・キューのアラート、大きなファイルのコピーは空いている時間帯に。DBサーバー:DBのディスクもIOPS・スループット利用率のアラート、DBインスタンスのスペックごとのディスク上限の確認。
数値の目安 HDDは約150、SATA SSDは数万、NVMeは数十万IOPS。クラウドの標準ディスク(AWS gp3)は3,000 IOPS、毎秒125MiBです。IOPSとは別にある毎秒の転送量の上限を大きなファイルのコピーが使い切ると、小さな書き込みまで詰まります。
グラフでは 上限で頭打ち · IOPS、ディスクのキュー長
確認箇所 iostat -x 1のr/s・w/s、rkB/s・wkB/s、aqu-sz、r_await・w_awaitを確認。クラウドはEBSのVolumeReadOps・VolumeWriteOps・VolumeQueueLengthと、上限超過の有無を示すVolumeIOPSExceededCheck・VolumeThroughputExceededCheck、インスタンス側のInstanceEBSIOPSExceededCheck・InstanceEBSThroughputExceededCheckを確認 該当する場合 毎秒の要求数や転送量が上限値で頭打ちになり、aqu-szとawaitが一緒に跳ね上がる。クラウドでは超過チェックのメトリクスが1 該当しない場合 %utilが100%でもawaitが低ければ、まだ余裕があることもある。要求を並列に処理するSSD・RAIDでは、%utilは上限を意味しない。上限に達していないのにawaitだけが高いなら、ディスク自体の遅延(dk-hdd)かfsync(dk-fsync) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく クラウドでは、ディスクの上限とは別に、サーバースペック(インスタンスタイプ)ごとにディスク帯域幅・IOPSの上限があります。高価なディスクを付けても、サーバーが小さければインスタンスの上限で頭打ちになります。
出典8件
ID dk-full · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ, ゲーム開発チーム・サーバー開発
ログとダンプがたまってディスクがいっぱいになると書き込みが失敗し、備えがなければサーバーが落ちます。
なぜ ログ・ダンプ・一時ファイルがたまって100% → すると 書き込み失敗。エラー処理がなければクラッシュ、あれば保存失敗 → 画面では 切断、進行状況のロールバック
症状 切断 , 不発・ロールバック
要因 ストール
誰に起きるか サーバー全体
いつ 長時間稼働するほど
担当 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 書き込み失敗を処理し、クラッシュさせる代わりに保存の再試行とアラート、不要なログ・ダンプの削減。
インフラチームの対応 サーバー機器・OS:ログのローテーション、容量のアラート、ログとデータのディスク分離。DBサーバー:DBのトランザクションログ(WAL、binlog)が、レプリケーションの停止・ログバックアップの漏れでたまっていないか監視。
グラフでは 徐々に上昇 · ディスク使用率
確認箇所 df -hの使用率とdf -iのinode使用率を確認し、サーバー・DBのログからENOSPCエラーを探す。DBは、PostgreSQLのpg_replication_slotsでactiveがfalseのスロット、MySQLのSHOW BINARY LOGSのファイル数・サイズ、SQL Serverのsys.databasesのlog_reuse_wait_desc、RDSはFreeStorageSpaceを確認 該当する場合 使用率が数日かけて着実に上がって100%に達した時刻と、クラッシュ・保存失敗の時刻が重なり、ログにENOSPCが残る 該当しない場合 空き容量が十分なのに書き込みが失敗するなら、権限・ファイルサイズ上限など別の原因 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく DBのトランザクションログ(WAL、binlogなど)は、レプリカが止まったりログのバックアップが抜けたりすると、削除されずにたまり続けます。このディスクがいっぱいになるとDBのすべての書き込みが止まり、保存・取引が一斉に失敗します。
出典8件
ID dk-backup · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ
深夜のバックアップ、ログの圧縮、セキュリティスキャンがディスクを独占すると、ゲームサーバーの読み書きが詰まります。
なぜ スケジュールされたバックアップ・圧縮処理が始まる → すると ディスクの帯域幅とIOPSの大半を占有 → 画面では 毎日同じ時刻にラグ
症状 カクつき , 入力遅延
要因 ストール, 遅延
誰に起きるか サーバー全体
いつ 一定の周期で
担当 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ
インフラチームの対応 サーバー機器・OS:バックアップ・圧縮・スキャン処理のI/O優先度を下げる、時刻の分散。DBサーバー:バックアップはレプリカで。
グラフでは 周期的なスパイク · ディスク利用率、ディスク待ち時間
確認箇所 sar -dで過去数日の記録(/var/log/saの日別ファイル。sadcが-S DISKでディスク項目まで収集している必要あり)の%util・await・aqu-szを日付ごとに重ねて確認し、その時刻にpidstat -d 1でkB_rd/s・kB_wr/sが最も大きいプロセスを探して、cron・systemdタイマーのスケジュールと照合 該当する場合 毎日同じ時刻にawaitと%utilが跳ね上がり、そのときバックアップ・圧縮・スキャンのプロセスがディスク読み書きの大半を占める 該当しない場合 跳ね上がる時刻が日によって違うなら、スケジュールされた処理の可能性は低い。その時刻のI/Oの大半がゲームサーバー自身なら、保存・ログ側(dk-fsync、dk-sync-log) 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
サーバーの遅延ロード Lazy loading on the server
ID dk-lazy-load · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
サーバーがダンジョン・マップのデータを初めて要求されたときにディスクから読むと、そのティックの間、全員が止まります。
なぜ 誰かが初めてダンジョン・エリアに入場 → すると サーバーがゲームスレッドでデータをディスクから読む → 画面では そのサーバーの全員が一瞬フリーズ
症状 フリーズ
要因 ストール
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 サーバー起動時の事前ロード、非同期ロード。
インフラチームの対応 スナップショットから作ったばかりのサーバーは、サービス投入前にディスクのウォームアップ(全ブロックを一度読む)を行うか、高速スナップショット復元機能を使う。
グラフでは 不定期なスパイク · サーバーのティック時間、ディスク読み込み
確認箇所 止まった時刻をゲームサーバーログのダンジョン・エリアへの初回入場の記録と突き合わせ、その瞬間のゲームサーバーのディスク読み込み(pidstat -dのkB_rd/s)と、perf trace --durationで長くかかったread・open呼び出しを確認。新しく立ち上がったクラウドサーバーなら、EBSのVolumeAvgReadLatencyを古いサーバーと比較 該当する場合 初めて入場した瞬間だけ止まり、同じ場所に2回目に入るときは止まらない。止まっている間、ゲームスレッドがファイルの読み込みで待っている 該当しない場合 すでにロード済みのエリアでも同じように止まるなら、ティックバジェット超過・GCなど別の原因 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく クラウドでスナップショット(ディスクのコピー)から作ったばかりのサーバーは、初めて読むブロックごとにリモートストレージから取得するため、普段よりはるかに遅くなります。オートスケーリングで新しく立ち上がったサーバーでだけ最初の入場が際立って長くかかるなら、これを疑います。
出典5件
ID dk-coredump · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
サーバーが落ちるときに数GBのメモリをディスクに書き出すため、再起動が数分遅れることもあります。
なぜ サーバーのクラッシュでメモリ全体をファイルに書き出す → すると 数GBを書き込む間は再起動できない → 画面では サーバーが落ちて切断された後、しばらく接続できない
症状 接続不可・無限ロード
要因 ストール
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 必要なメモリだけを含む小さなダンプ(ミニダンプ)方式の検討、クラッシュ原因の修正。
インフラチームの対応 ダンプサイズの制限(OSのコアダンプ設定)、高速なディスク、再起動とダンプの分離(ダンプの圧縮・アップロードは再起動後に別途処理)。
グラフでは 接続が一斉に切れる · 接続数、サーバーの再起動時刻
確認箇所 クラッシュ時刻とコアファイルのサイズ(coredumpctl list・info、またはcore_patternが指す場所のファイル)、ファイルの書き込みが終わった時刻、サービスが再び立ち上がった時刻を並べ、その間のiostat -xのwkB/sを確認 該当する場合 クラッシュ後、数GBのコアファイルを書き込む間ディスク書き込みが上限近くに張り付き、書き出しが終わってから再起動が始まる 該当しない場合 コアダンプが無効か小さく済んだのに再起動が遅いなら、マップのロードやDBのコールドキャッシュ(db-cold-cache)など、サーバーの起動処理側 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
ID dk-hdd · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ, ゲーム開発チーム・サーバー開発
HDDはヘッドがプラッタ上を移動する(シーク、seek)必要があるため、散らばったデータの読み書きに1回あたり10ms近くかかります。
なぜ 古いサーバーや低価格ストレージでHDDを使用 → すると ランダムな読み書きのたびに約10ms → 画面では 全体的な保存・ロードの遅延
症状 入力遅延
要因 遅延
誰に起きるか サーバー全体
いつ 常に
担当 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 シーケンシャル書き込み中心の設計。
インフラチームの対応 サーバー機器・OS:SSDに交換(ランダムな読み書きが多い保存用ディスクから)。DBサーバー:ランダムな読み書きが最も多いDBディスクを先にSSDに交換。
グラフでは 最初から常に高い · ディスクの読み書き遅延(r_await・w_await)
確認箇所 lsblk -d -o NAME,ROTAで回転ディスク(HDD)かどうかを確認し、iostat -x 1のr/s・w/sとr_await・w_awaitを確認。仮想サーバーはクラウド・ストレージの仕様でディスクの種類を確認 該当する場合 回転ディスクで、毎秒の要求が数十〜100件あまりの水準なのに、r_await・w_awaitが常に数ms〜数十ms 該当しない場合 SSDなのに遅延が高いなら、キューの飽和(dk-iops)かバーストクレジットの枯渇(dk-burst)側 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
L12 データベース
原因16件 · メインページの章
インデックスのないクエリ Missing index / full table scan
ID db-no-index · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
インデックスがないと、条件に合う行を探すためにテーブル全体を読む必要があります(フルスキャン)。
なぜ 新機能のデプロイで、インデックスのない条件検索が追加される → すると 数百万行をすべてスキャンし、クエリ1つに数百ms〜数秒 → 画面では 郵便受け・取引履歴のロード遅延、コネクションがふさがって他の要求まで待たされる
症状 入力遅延 , 接続不可・無限ロード
要因 遅延, ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 新しいクエリはデプロイ前に実行計画をレビュー、インデックスの追加、更新系のクエリ(UPDATE・DELETE)もインデックスが効くか確認。
インフラチームの対応 スロークエリログの監視、フルスキャンのクエリを見つけてゲーム開発チームに共有、運用中のインデックス追加はロックの短いオンライン方式で適用。
数値の目安 インデックスがあれば数ms、なければデータ量に比例して遅くなり、大きなテーブルでは数百〜数万倍。
グラフでは ある時点から階段状に上昇 · DBクエリの遅延、読み取った行数
確認箇所 MySQLはslow query log(log_queries_not_using_indexesを有効にすると、インデックスを使わなかったクエリも記録)のRows_examined・Rows_sent、performance_schemaのevents_statements_summary_by_digestのSUM_NO_INDEX_USED・SUM_ROWS_EXAMINEDを確認し、EXPLAINを実行。PostgreSQLはpg_stat_user_tablesのseq_scan・seq_tup_readを確認し、EXPLAINを実行 該当する場合 デプロイ後に新しく現れたクエリが、返した行(Rows_sent)より数千倍多い行を読み(Rows_examined)、EXPLAINにテーブルのフルスキャン(MySQLはtype ALL、PostgreSQLはSeq Scan)が出る。大きなテーブルのseq_tup_readがデプロイ時刻から急激に増える 該当しない場合 インデックスが効いているのに遅いなら、ロック待ち(db-hot-row、db-ddl-lock)か実行計画の変化(db-plan-flip)。小さなテーブルのフルスキャンは正常なこともある 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 影響は読み込みが遅くなるだけにとどまりません。インデックスなしの更新系クエリ(UPDATE・DELETE)は、DBによってはスキャンした行までロックし、無関係なプレイヤーの保存まで止めてしまうことがあります。
出典8件
ID db-hot-row · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
全員が同じ行(ギルド倉庫、オークションの人気アイテム、サーバー全体のカウンター)を更新しようとすると、ロックを取れるのは1人ずつです。
なぜ イベント・人気アイテムで同じ行に更新が集中 → すると ロックを取れるまで要求が待たされる → 画面では 取引失敗、「しばらくしてからもう一度お試しください」、タイムアウト
症状 不発・ロールバック , 入力遅延
要因 ストール, 遅延
誰に起きるか 特定の機能だけ
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 行の分割(シャーディングしたカウンター)、トランザクションを短く、メモリで集約して一度に反映。
インフラチームの対応 行ロックの待ち時間・件数を監視し、競合が集中する行を見つけて共有。
数値の目安 1つの要求がロックを10ms保持していると、その行は1秒に最大100回しか更新できません。トランザクションの中に別サーバーとの往復が挟まると、その分さらに減ります。
グラフでは 人数・負荷に連動して上昇 · 行ロックの待ち数・待ち時間
確認箇所 MySQLはInnodb_row_lock_waits・Innodb_row_lock_timeの増加量とInnodb_row_lock_current_waitsを確認し、sys.innodb_lock_waitsで誰が誰を待っているかを探す。PostgreSQLはpg_stat_activityでwait_event_typeがLockのセッション、pg_locksでgrantedがfalseの要求を確認し、log_lock_waits(デフォルト無効)を有効にすると長く待ったロックがログに残る 該当する場合 イベント・人数に連動してロック待ちが急増し、待っている要求の大半が同じテーブルの同じ行(同じキー)を指している 該当しない場合 待ちが複数のテーブル・行に均等に散らばっているなら、ディスク・CPUの飽和側。1つのセッションがロックを長く保持して離さないなら、長時間開いたままのトランザクション(db-long-tx) 確認手段 インフラのツールで確認(ゲームコード不要)
出典7件
ID db-deadlock · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
2つのトランザクション(ひとまとまりで処理されるDB操作)が互いに相手のロックした行を待つと、DBが片方を強制的に取り消します。
なぜ 取引Aはアイテム→通貨、Bは通貨→アイテムの順にロック → すると DBがデッドロックを検知して片方をロールバック → 画面では 取引・製作がときどき失敗、アイテムが元に戻る
症状 不発・ロールバック , 入力遅延
要因 パケットロス, ストール
誰に起きるか 特定の機能だけ
いつ 人が集中したとき, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 ロック順序の統一、トランザクションを短く、失敗時の自動再試行。
インフラチームの対応 デッドロック検知を有効にしておき、デッドロックの記録を収集して共有、検知を無効にしたMySQLサーバーはロック待ちの上限(デフォルト50秒)を短縮。
数値の目安 検知までに、MySQL(InnoDB)はほぼ即時、PostgreSQLはデフォルトで1秒、SQL Serverは最大5秒ほどかかります。その間、両方の要求が止まっています。同時要求が非常に多いためにMySQLの検知を無効にしているサーバーでは、ロック待ちの上限(デフォルト50秒)まで待ちます。
グラフでは 不定期なスパイク · デッドロック数、取引失敗数
確認箇所 MySQLはSHOW ENGINE INNODB STATUSのLATEST DETECTED DEADLOCK(直近の1件)、innodb_print_all_deadlocksを有効にするとエラーログに残るすべてのデッドロック、INFORMATION_SCHEMA.INNODB_METRICSのlock_deadlocksを確認。PostgreSQLはpg_stat_databaseのdeadlocks、SQL Serverはデフォルトで有効なsystem_healthセッションのxml_deadlock_reportを確認。ゲームサーバー側のエラーコードはMySQL 1213、PostgreSQL 40P01、SQL Server 1205 該当する場合 取引・製作の失敗時刻にデッドロック数が増え、記録された2つのトランザクションが同じテーブル群を互いに逆の順序でロックしている 該当しない場合 デッドロック数は変わらないのに失敗するなら、ロック待ちの上限超過(MySQLエラー1205)かホットスポット(db-hot-row) 確認手段 インフラのツールで確認(ゲームコード不要)
出典10件
コネクションプールの枯渇 Connection pool exhaustion
ID db-pool · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
DBとの接続数は決まっているため、遅いクエリが接続を占有すると、残りの要求は待たされます。
なぜ 遅いクエリや要求の殺到で、すべての接続が使用中 → すると 新しい要求は接続が空くまで待つ → 画面では ログインの無限ロード、保存の遅延、タイムアウト
症状 接続不可・無限ロード , 入力遅延
要因 ストール, 遅延
誰に起きるか サーバー全体, 特定の機能だけ
いつ 接続直後・メンテ明け, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 遅いクエリの排除、プールサイズと待ちタイムアウトの調整(プールをむやみに大きくしない)、機能別のプール分離。
インフラチームの対応 DBの最大接続数とCPU・IOPSの余裕を確認、増設・オートスケーリングの前にサーバー台数 × プールサイズが最大接続数以内か確認、コネクション待ち・ロック待ちのメトリクスを監視に追加。
数値の目安 必要な接続数は「毎秒の要求数 × 1件が接続を占有する時間」で見積もります。1秒に2,000件、1件あたり5msなら、平均10本が常に使用中です。集中するときに備えて、通常はその2〜3倍を用意します。クエリが150msに遅くなると、同じ要求数で300本が必要になります。
グラフでは 上限で頭打ち · 使用中のDB接続数、コネクション待ち時間
確認箇所 DB側でゲームサーバーごとの接続状態を集計。MySQLはSHOW PROCESSLISTのHost・Command(アイドル状態の接続はSleep)・TimeとThreads_connected・Threads_running、拒否された接続数Connection_errors_max_connectionsを確認。PostgreSQLはpg_stat_activityをclient_addr・stateでまとめて集計。ゲームサーバーのコネクションプールライブラリが待ち数・待ち時間を出力していれば、合わせて確認 該当する場合 1台のゲームサーバーの接続がプールサイズいっぱいまですべてクエリ実行中で、アイドル状態の接続が0の間、ログイン・保存が待たされる。またはDB全体の接続数がmax_connectionsに達し、新しい接続が拒否される 該当しない場合 アイドル状態の接続が十分あるのに遅いなら、クエリ自体の遅延(db-no-index、db-hot-row)かDBリソースの飽和側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく プールをむやみに大きくすると、DBのCPUとロック競合が増えるだけで、全員が一緒に遅くなります。また、サーバー台数 × プールサイズがDBの最大接続数を超えると、増設したサーバーや再起動したサーバーが接続すら確立できません。オートスケーリングやメンテ明けによく起きます。
出典6件
ID db-replica-lag · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
書き込みはプライマリに、読み込みはレプリカから行う構成で、レプリカの追従が遅れると、書いたばかりの内容が見えません。
なぜ プライマリに書き込みが集中し、レプリカが数秒遅れる → すると 保存したばかりの内容をレプリカから読むと、まだ反映されていない → 画面では 買ったばかりのアイテムが表示されない、取引所の価格が古い値のまま、重複付与のバグ
症状 不発・ロールバック
要因 遅延
誰に起きるか 特定の機能だけ
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 書いたばかりのデータはプライマリから読む、付与済みかどうかの確認と付与はプライマリで1つのトランザクションに(ユニークキーや条件付きUPDATEで重複を防止)。
インフラチームの対応 レプリケーション遅延のアラート、レプリカのスペックをプライマリ以上にして並列レプリケーションを適用、大量削除は細かく分けて実行、レプリカで長時間動く集計クエリの管理。
グラフでは 人数・負荷に連動して上昇 · レプリケーション遅延(秒)
確認箇所 MySQLはレプリカでSHOW REPLICA STATUSのSeconds_Behind_Source(8.0.22より前のバージョンはSHOW SLAVE STATUS)を確認。PostgreSQLはプライマリのpg_stat_replicationのwrite_lag・flush_lag・replay_lag、RDSはReplicaLagを確認 該当する場合 「表示されない」という報告の時刻に遅延が数秒以上あり、遅延が解消した後に見直すと正常。書き込みの殺到や大量削除、レプリカの長い集計クエリの時刻に遅延が大きくなる 該当しない場合 遅延が0付近なのに表示されないなら、ゲームサーバーのキャッシュや同期側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 書き込みが多くなくても遅れることがあります。プライマリで10分かかった大量削除が1つあると、レプリカでも再実行される間、その分だけ遅れます。レプリカで長時間動く集計クエリも追従を遅らせます。
出典6件
ID db-checkpoint · 主担当 インフラチーム・DBインフラ
DBがメモリ上の変更分を定期的にまとめてディスクに書き込む瞬間、クエリが遅くなります。
なぜ 変更分がたまり、定期的にディスクへ書き出す → すると その瞬間ディスクの負荷が上がり、クエリが遅延 → 画面では 定期的に保存・ロードが遅くなる
症状 入力遅延 , カクつき
要因 遅延
誰に起きるか サーバー全体, 特定の機能だけ
いつ 一定の周期で
担当 主担当 インフラチーム・DBインフラ
インフラチームの対応 チェックポイントを細かく分けて平準化、トランザクションログ(redoログ、WAL)を十分な大きさに、高速なディスク。
グラフでは 周期的なスパイク · DBクエリの遅延、ディスク書き込み量
確認箇所 PostgreSQLはlog_checkpoints(最近のバージョンはデフォルトで有効)のログにあるチェックポイントの時刻と書き込んだバッファ数、チェックポイントの回数(17以降はpg_stat_checkpointerのnum_timed・num_requested、16以前はpg_stat_bgwriterのcheckpoints_timed・checkpoints_req)、checkpoint_warningの警告を確認。MySQLはSHOW ENGINE INNODB STATUSのLOGセクションで、Log sequence numberとLast checkpoint atの差を確認。サーバーのディスク書き込み量・書き込み遅延も重ねて確認 該当する場合 クエリ遅延が跳ねた時刻がチェックポイントの時刻と重なり、そのときディスク書き込み量と書き込み遅延が跳ね上がる。PostgreSQLで要求によるチェックポイント(num_requested)が時間によるチェックポイント(num_timed)よりはるかに多ければ、WALが頻繁にmax_wal_sizeに達してチェックポイントが前倒しになっているとみなす 該当しない場合 チェックポイントの時刻と無関係な周期で跳ねるなら、バックアップ・バッチ(dk-backup、db-batch) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 変更の記録を保持するトランザクションログ(MySQLのredoログ、PostgreSQLのWAL)を小さく設定しすぎると、ログが満杯になるたびに、DBが急いでチェックポイントをまとめて実行するため、書き込みスループットが一時的に大きく落ちます。
出典7件
ID db-cold-cache · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
DBを再起動するとメモリ上のキャッシュが空になっているため、しばらくはすべての読み込みがディスクから行われます。
なぜ メンテナンスでDBを再起動 → すると よく使われていたデータがメモリになく、ディスクから読む → 画面では メンテ明けしばらくログイン・ロードが遅い
症状 接続不可・無限ロード , 入力遅延
要因 遅延
誰に起きるか サーバー全体
いつ 接続直後・メンテ明け
担当 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 段階的なオープン(ログイン待機列を使い、ログインできる人数を少しずつ増やす)。
インフラチームの対応 再起動後のキャッシュのウォームアップ(バッファプールの保存・復元設定を確認)、スナップショットから復元したDBはディスクも事前に読み込む。
グラフでは 接続直後・メンテ明けに急増 · ディスク読み込み、バッファキャッシュのヒット率
確認箇所 MySQLはInnodb_buffer_pool_reads(バッファプールになくディスクから読んだ回数)とInnodb_buffer_pool_read_requestsの比率、ウォームアップの進行状況Innodb_buffer_pool_load_statusを確認。PostgreSQLはpg_stat_databaseのblks_read・blks_hitを確認。DBサーバーのディスク読み込み数も合わせて確認 該当する場合 再起動直後にディスク読み込みが跳ね上がってヒット率が低く、時間とともに回復し、その間ログイン・ロードが遅い 該当しない場合 ヒット率が平常どおりなのにメンテ明けに遅いなら、ログイン殺到・N+1(db-login-storm)かコネクションプール(db-pool) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく MySQLは停止時にバッファプールのページ一覧を保存し、起動時にバックグラウンドで読み込み直しますが、すべて埋まるまでには時間がかかります。クラウドでDBをスナップショット(ディスクのコピー)から復元した場合は、ディスク自体も初めて読むブロックごとに遅いため、さらに長引きます。
実際の事例 Roblox 2021: Robloxの73時間障害:サービスディスカバリ(Consul)クラスターでの競合
出典5件
ID db-login-storm · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
キャラクター1体を読み込むたびに数十回の個別クエリを発行していると、数万人の同時ログインは数百万件のクエリになります。
なぜ キャラクターのロード時にアイテム・スキル・クエストを個別にクエリ → すると メンテ明けの同時ログインでクエリが急増 → 画面では ログインの無限ロード、プレイ中のユーザーの保存まで滞る
症状 接続不可・無限ロード , 入力遅延
要因 ストール, 遅延
誰に起きるか サーバー全体
いつ 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 まとめて1回で取得、ログイン待機列、キャッシュ、ORMの遅延ロードが生むクエリ数の点検。
インフラチームの対応 呼び出し回数の多いクエリのランキングを出して共有、メンテ明けのログイン時間帯のクエリ数・コネクション数を監視。
グラフでは 接続直後・メンテ明けに急増 · DBの秒間クエリ数、ログイン数
確認箇所 メンテ明けのログイン数とDBの秒間クエリ数(MySQLはQuestionsの増加量)を重ねて、ログイン1件あたりのクエリ数を計算。呼び出し回数が上位のクエリは、MySQLはevents_statements_summary_by_digestのCOUNT_STAR、PostgreSQLはpg_stat_statementsのcallsで抽出 該当する場合 ログイン1件あたりのクエリが数十件あり、上位のクエリがキャラクターID 1つで検索する同じ形の短いクエリばかり。アップデート後にログインあたりのクエリ数が増えたなら、そのアップデートが発端 該当しない場合 ログインあたりのクエリ数は少ないのにクエリ1つ1つが遅いなら、コールドキャッシュ(db-cold-cache)かインデックス(db-no-index) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく ORM(DBへのクエリを代わりに組み立ててくれるライブラリ)の遅延ロード(lazy loading)が、開発者も気づかないうちにこうしたクエリを生みます。開発サーバーではキャラクターが数体しかないので目立たず、本番の同時ログインで初めて表面化します。
出典5件
大規模なバッチ処理 Batch jobs during service
ID db-batch · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ランキング集計、郵便の一括送信、古いデータの整理をサービス中に実行すると、ロックとディスクを占有します。
なぜ サービス時間中に大量の処理を実行 → すると 広い範囲のロック、ディスク・CPUの占有 → 画面では 特定の時間帯に取引・保存が失敗、ロード遅延
症状 入力遅延 , 不発・ロールバック
要因 遅延, ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ 一定の周期で
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 細かく分けて少しずつ、集計はレプリカで。
インフラチームの対応 集計用レプリカの提供、バッチは空いている時間帯に予約、ロックエスカレーション・ギャップロック待ちの監視。
グラフでは 周期的なスパイク · DBクエリの遅延、ロック待ち
確認箇所 ラグが出た時刻に動いていた長いクエリを探す。MySQLはslow query log、PostgreSQLはpg_stat_activityのquery_start・queryを確認し、同じ時刻のロック待ちのメトリクスとバッチのスケジュール(cron、DBのイベントスケジューラー)を照合。SQL Serverはlock_escalation拡張イベントでロックエスカレーションを記録 該当する場合 毎回同じ時刻に大量のUPDATE・DELETE・集計クエリが動き、その間ロック待ちとディスク利用率がそろって上がる 該当しない場合 その時刻に長いクエリがなければ、チェックポイント(db-checkpoint)かサーバーのバックアップ(dk-backup) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく SQL Serverは、1つのステートメントが約5,000個を超える行ロックを取ると、テーブルロックに切り替えます(ロックエスカレーション)。その瞬間、同じテーブルを使うすべての要求が止まります。MySQLもデフォルト設定では、範囲条件で更新すると行と行の間の隙間までロックし(ギャップロック)、新しい行の挿入を止めます。
出典4件
ID db-failover · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
プライマリが落ちてスタンバイDBに切り替わる間は書き込みができず、レプリケーションが間に合わなかった最後のデータは失われることがあります。
なぜ プライマリの障害でスタンバイDBが昇格 → すると 切り替え中は数秒〜数分書き込み不可、非同期レプリケーションならレプリカに届いていないデータが失われる可能性 → 画面では 一時的にすべての保存が失敗、アイテム・経験値のロールバック
症状 不発・ロールバック , フリーズ , 切断 , 接続不可・無限ロード
要因 ストール, パケットロス
誰に起きるか サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 再試行可能な保存、切れた接続をすぐに捨てて新しいアドレスへ接続し直す設定(コネクションプール・DNSキャッシュ)、フェイルオーバー訓練で再接続を確認。
インフラチームの対応 同期・準同期レプリケーション(書き込み遅延とのトレードオフ)、フェイルオーバー訓練、切り替え時間・レプリケーション遅延の監視。
数値の目安 マネージドDBの自動フェイルオーバーは通常数十秒〜2分。非同期レプリケーションなら、レプリケーション遅延の分(1秒未満〜数秒)だけ直近の保存が失われることがあります。
グラフでは 接続が一斉に切れる · DB接続数、書き込みエラー数
確認箇所 DB側のフェイルオーバーの記録(RDSはイベントRDS-EVENT-0013がフェイルオーバー開始・RDS-EVENT-0049がフェイルオーバー完了、自前で運用するDBは昇格ログ)と、ゲームサーバーのDB接続数・接続エラー数を1つのグラフに並べる。非同期レプリケーションなら、障害直前のレプリケーション遅延(RDSのReplicaLag、PostgreSQLのpg_stat_replicationのreplay_lag)も確認 該当する場合 保存の失敗が1つの区間に集中し、その区間がフェイルオーバーの開始から完了までと重なる。ロールバックされた分が障害直前のレプリケーション遅延とほぼ同じ。切り替え完了後もエラーが続くゲームサーバーは、古いアドレスで確立した接続を使い続けている 該当しない場合 フェイルオーバーの記録がない時刻の接続断は、ネットワークかDBの過負荷側 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 Riot Games 2021: League of Legends EUWの5時間障害:補助的なDB一つでサーバー全体が停止
出典7件
ID db-save-interval · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
負荷を減らすために数分に1回しか保存しないと、その間にサーバーが落ちた場合に進行状況が失われます。
なぜ キャラクターの状態を数分ごとに1回保存 → すると その間にサーバーのクラッシュ・障害が発生 → 画面では 再接続すると数分前の状態(ロールバック)
症状 不発・ロールバック
要因 パケットロス
誰に起きるか サーバー全体, 特定の場所・チャンネル
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 重要なイベント(取引、レアアイテムの獲得)は即時保存、変更ログの記録。
インフラチームの対応 保存間隔を短くしたときに増える書き込みに耐えられるだけの、DBのIOPS・CPUの余裕を確認。
グラフでは 接続が一斉に切れる · 接続数、ロールバックの報告数
確認箇所 クラッシュ・障害の時刻と、ロールバックを報告したキャラクターの最終保存時刻(ゲームサーバーの保存ログやDBの更新日時カラム)を並べる 該当する場合 巻き戻った時点がクラッシュ直前の最終保存時刻と一致し、失われた時間が保存間隔より短い 該当しない場合 ゲームサーバーのログには保存完了と残っているのに巻き戻ったなら、DBのフェイルオーバーによるデータ消失(db-failover)か、レプリカから読んだ古い値(db-replica-lag) 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
キャッシュスタンピード Cache stampede / thundering herd
ID db-cache-stampede · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
人気データのキャッシュが同時に期限切れになると、数千件の要求が一斉にDBへ殺到します。
なぜ Redisなどに保存した人気データが同時に期限切れ → すると 同じデータを作り直そうとする要求が一斉にDBへ殺到 → 画面では DBの過負荷で複数の機能が次々に遅くなったり止まったりする
症状 入力遅延 , フリーズ , 接続不可・無限ロード
要因 ストール, 遅延
誰に起きるか サーバー全体
いつ 一定の周期で, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 期限切れの時刻をランダムに分散、1つの要求だけが更新し残りは古い値を使う。
インフラチームの対応 Redisの再起動・障害時にキャッシュが丸ごと空にならないよう、レプリカ・自動フェイルオーバーを構成、キャッシュが空になっても耐えられるDBの余裕を確認。
グラフでは 周期的なスパイク · キャッシュのヒット率、DBの秒間クエリ数
確認箇所 Redis INFOのkeyspace_hits・keyspace_misses(ヒット率)、expired_keys、再起動の有無(uptime_in_seconds)をDBの秒間クエリ数と重ねて確認し、その瞬間にDBで同じクエリがいくつ同時に動いているか(MySQLはSHOW PROCESSLIST、PostgreSQLはpg_stat_activity)を数える 該当する場合 キャッシュミスが一瞬で急増した時刻にDBのクエリ数も跳ね上がり、同時に動いているクエリの大半が同じデータを読む同じクエリ。人気キーの期限切れの周期やRedisの再起動時刻と重なる 該当しない場合 キャッシュミスは平常どおりなのにDBのクエリだけが増えるなら、ログイン殺到(db-login-storm)かバッチ(db-batch) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく Redisが再起動したり、障害でキャッシュが丸ごと空になったりしても、同じことが起きます。キャッシュを当てにしてDBを小さく見積もった構成ほど危険です。
出典6件
長時間開いたままのトランザクション Long-running transaction / MVCC purge lag
ID db-long-tx · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
1つのトランザクションが長く開いたままだと、ロックを持ち続けるうえ、DBが古いバージョンのデータを整理(purge)できないため、全体が徐々に遅くなります。
なぜ トランザクションを開いたまま別サーバーの応答を待つ、またはサービス中にプライマリで長い集計クエリを実行 → すると 取ったロックが解放されず、整理すべき古いバージョンのデータがたまり続ける → 画面では その行を使う機能がタイムアウト、数時間かけて保存・読み込みが全体的に遅くなる
症状 入力遅延 , 不発・ロールバック
要因 遅延, ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ 長時間稼働するほど, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 トランザクション内でネットワーク呼び出し・ユーザー入力を待たない、集計クエリはレプリカで。
インフラチームの対応 長時間開いたままのトランザクションのアラートと強制終了、集計用レプリカの提供、UNDOログ・デッドタプルの増加の監視。
グラフでは 徐々に上昇 · UNDOログの長さ(History list length)、デッドタプル数
確認箇所 MySQLはINFORMATION_SCHEMA.INNODB_TRXのtrx_startedで最も古いトランザクションを探し、SHOW ENGINE INNODB STATUSのTRANSACTIONSセクションに出るHistory list length(まだ整理できていないUNDOログの量)を確認。PostgreSQLはpg_stat_activityのxact_startと、stateがidle in transactionのセッション、pg_stat_user_tablesのn_dead_tupを確認 該当する場合 数分〜数時間経ったトランザクションがあり、その間History list lengthやn_dead_tupが上がり続け、そのトランザクションを終えた後に整理(purge・VACUUM)が走って減る 該当しない場合 古いトランザクションがないのに全体的に遅いなら、チェックポイント(db-checkpoint)かディスク側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく DBは、読む側が更新前の状態を見られるように、古いバージョンを残しておきます(MVCC)。最も古いトランザクションが終わるまでこの記録は消せないため、1つのトランザクションが数時間開いたままだと、MySQLではUNDOログが、PostgreSQLではVACUUMが整理できないデッドタプル(dead tuple、不要になった古い行)がたまります。SQL Serverではトランザクションログが縮まず、ディスクを埋めてしまうこともあります。
出典7件
Redisの遅いコマンド Redis blocking commands (single-threaded)
ID db-redis-block · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
Redisはコマンドを1つずつ順番に処理するため、遅いコマンドが1つあると、その後ろのすべての要求が止まります。
なぜ サービス中にKEYSで全件検索、要素が数百万個あるランキング・リストを丸ごと読んだり削除したりする → すると そのコマンドが終わるまで、他のすべての要求が待たされる(数十ms〜数秒) → 画面では セッション・ランキング・キャッシュを使う機能が一斉に一瞬止まる、ログイン遅延
症状 フリーズ , 入力遅延 , 接続不可・無限ロード
要因 ストール, 遅延
誰に起きるか サーバー全体, 特定の機能だけ
いつ ときどきランダムに, 一定の周期で
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 KEYSの代わりにSCAN、大きなキーの分割、削除はUNLINK(バックグラウンド削除)、同じ秒に集中する期限切れ時刻の分散。
インフラチームの対応 遅いコマンドの記録(SLOWLOG)の監視、KEYSのような危険なコマンドは本番サーバーで禁止、大きなキーの定期点検、THPを無効にしてfork用のメモリの余裕を確保、RDB・AOFの保存はレプリカで。
数値の目安 通常のコマンドは1ms未満。要素数百万個を一度に扱うと、数百msから数秒かかることもあります。
グラフでは 不定期なスパイク · Redisの応答遅延、遅いコマンドの数
確認箇所 SLOWLOG GETでslowlog-log-slower-thanを超えたコマンドを確認し、CONFIG SET latency-monitor-thresholdでレイテンシモニター(デフォルト無効)を有効にしてから、LATENCY LATEST・LATENCY DOCTORでfork・expire-cycleのようなイベントごとの遅延を確認。INFOのlatest_fork_usecとredis-cli --bigkeysで、fork時間と大きなキーも確認 該当する場合 止まった時刻のSLOWLOGにKEYSや大きなキーを丸ごと扱うコマンドが残っている、またはLATENCYに同じ時刻のfork・expire-cycleイベントが数十ms以上で記録されている 該当しない場合 SLOWLOG・LATENCYが空なのにゲームサーバー側でだけ遅いなら、ネットワークかゲームサーバー内部の待ち(SLOWLOGはコマンドの実行時間だけを測り、クライアントとのやり取りの時間は含まない) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 保存ファイル(RDBスナップショット)を作ったり、AOFをリライトしたりするためにプロセスを複製(fork)する瞬間にも止まります。最近のサーバーではメモリ1GBあたり約10msなので、30GBなら300msほどです。ヒュージページ(THP)を有効にしていると、fork後の書き込みのたびにヒュージページを丸ごとコピーする(copy-on-write)ため、停止時間とメモリ使用量が大きく増えます。そのため通常はTHPを無効にし、メモリに十分な余裕を持たせます。同じ秒に期限切れになるキーが非常に多いときも、Redisが削除処理のために一瞬止まります。
出典7件 Diagnosing latency issues Redis 要求を1つのスレッドが順番に処理するため、遅いコマンドが後ろをすべて止める、KEYSの代わりにSCAN、forkは物理サーバー・最新VMの実測で1GBあたり約9〜13ms、THPはfork後のコピーで遅延・メモリが急増、同じ秒に大量の期限切れが起きると停止 KEYS Redis 本番環境では細心の注意を払って使うこと、大きなDBでは性能を大きく損なうおそれがある(エントリーモデルのノートPCでキー100万個に40ms) UNLINK Redis キーを即座に切り離し、メモリの回収は別スレッドで行う非同期削除 SLOWLOG Redis slowlog-log-slower-thanを超えたコマンドを記録するスローログ、実行時間にはクライアントとのI/Oは含まれない Redis latency monitoring Redis latency-monitor-thresholdのデフォルトは0(無効)、LATENCY LATEST・LATENCY DOCTOR、fork・expire-cycleのようなイベントごとの遅延を記録 INFO Redis latest_fork_usec:直近のforkにかかった時間(マイクロ秒) Redis CLI Redis --bigkeys:キー空間を走査して大きなキーを探す
実行計画の変化によるクエリ遅延 Query plan regression (stats, parameter sniffing)
ID db-plan-flip · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
コードは変わっていないのに、DBが同じクエリの処理方法(実行計画)を変えると、昨日2msだったクエリが今日は数百msになります。
なぜ 統計情報の自動更新、DBの再起動、データ分布の変化で、DBが実行計画を立て直す → すると インデックスを使わない計画が選ばれ、同じクエリが数十〜数百倍遅くなり、コネクションがふさがる → 画面では デプロイもなかったのに特定の機能のロードが急に遅くなり、他の要求まで待たされる
症状 入力遅延 , 接続不可・無限ロード
要因 遅延, ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 値によって結果の件数が大きく変わるクエリは分けて使うか、実行計画のヒントを検討、インデックスが確実に効くクエリの設計。
インフラチームの対応 スロークエリと実行計画の記録の監視、良い計画の固定(SQL Serverのクエリストアなど)、統計情報の更新時刻の管理。
グラフでは ある時点から階段状に上昇 · クエリごとの平均実行時間
確認箇所 同じ形のクエリの平均時間を定期的に集めて推移を確認。MySQLはevents_statements_summary_by_digestのAVG_TIMER_WAIT、PostgreSQLはpg_stat_statementsのmean_exec_time(12以前はmean_time)。遅くなる前後の実行計画は、EXPLAINやPostgreSQLのauto_explainで、SQL Serverはクエリストアの「機能低下したクエリ」(Regressed Queries)画面で比較 該当する場合 デプロイのなかった時刻に1つのクエリの平均時間が階段状に数十倍に上がり、その時点が統計情報の更新・DBの再起動と重なり、実行計画が変わっている 該当しない場合 実行計画は変わっていないのに遅くなったなら、データの増加、ロック待ち(db-hot-row)、ディスク側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく SQL Serverは、最初に渡された値に合わせて立てた計画を再利用します(パラメータスニッフィング)。アイテムが数個しかない新規キャラクターで立てた計画が、アイテムを数万個持つ古いキャラクターに使われると大きく遅くなり、その逆もよくあります。再起動で計画が消えると正常に戻り、また悪化することもあります。
出典7件
ID db-ddl-lock · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
サービス中にテーブルへカラムやインデックスを追加すると、一瞬だけ必要なロック1つのために、そのテーブルを使うすべての要求が待たされることがあります。
なぜ ホットフィックスでサービス中のテーブルにカラム・インデックスを追加 → すると スキーマ変更が先に開いていた長いトランザクションを待ち、後から来るすべての要求はそのスキーマ変更を待つ → 画面では そのテーブルを使う機能(インベントリ、郵便など)が丸ごと止まり、タイムアウト
症状 入力遅延 , 不発・ロールバック , 接続不可・無限ロード
要因 ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ ときどきランダムに, 接続直後・メンテ明け
担当 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 スキーマ変更を含むホットフィックスはDBインフラと日程を調整、新しいカラムがなくても動くコードを先にデプロイ。
インフラチームの対応 ロック待ちの上限を短く設定し、失敗したら再試行、長いトランザクションがないときに実行、オンラインスキーマ変更ツールの使用、大きなテーブルはメンテナンス時間に。
グラフでは ある時点から階段状に上昇 · ロック待ちのセッション数、そのテーブルのクエリ遅延
確認箇所 MySQLはSHOW PROCESSLISTでStateがWaiting for table metadata lockのセッションを数え、sys.schema_table_lock_waitsでブロックしているセッション(blocking_pid)を探す。PostgreSQLはpg_locksでgrantedがfalseの要求とAccessExclusiveLockを確認し、pg_blocking_pids()でブロックしているセッションを探す 該当する場合 スキーマ変更を開始した時刻から、そのテーブルを使うすべてのクエリがロック待ちで積み上がり、先頭に終わっていないトランザクションかスキーマ変更のステートメントがある 該当しない場合 待ちが特定の行にだけ集中し、同じテーブルの他の行は問題なく処理されているなら、ホットスポット(db-hot-row) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく MySQLはスキーマを変更するときにメタデータロックを、PostgreSQLは最も強いテーブルロックを短時間取ります。変更自体は一瞬で終わっても、先に終わっていないトランザクションが1つあると、その後ろにすべての要求が並んで待ちます。
出典8件
L13 サーバー構成と運用
原因13件 · メインページの章
ID in-gateway · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
クライアントとゲームサーバーの間に中継サーバーを置くと、経由するたびに処理時間が加わり、そのサーバーが単一障害点になります。
なぜ クライアント ↔ ゲートウェイ ↔ ゲームサーバーの構成 → すると 中継サーバーでの処理・待ちが加わり、過負荷になると全員に影響 → 画面では 全体のPingが上昇、ゲートウェイ障害時はそこを経由するユーザー全員が切断
症状 入力遅延 , 切断
要因 遅延, ストール
誰に起きるか サーバー全体
いつ 人が集中したとき, 常に
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:ゲートウェイを複数台に増やせる構成、ゲートウェイが落ちても別のゲートウェイにつなぎ直せばキャラクターがそのまま引き継がれる仕組み(セッション再接続)。クライアント:ゲートウェイとの接続が切れたら自動で再接続。
インフラチームの対応 ゲートウェイの水平スケーリング(台数追加)、ゲートウェイごとのCPU・接続数・処理遅延の監視。
数値の目安 同じデータセンター内なので、普段は1回の経由で1ms未満です。ゲートウェイが過負荷になると数十〜数百msに延びます。
グラフでは 人数・負荷に連動して上昇 · ゲートウェイの処理遅延、ゲートウェイのCPU・接続数
確認箇所 ゲートウェイのCPU・接続数とゲートウェイのソケットのRecv-Q(ss・netstat)、ゲートウェイを通る前と後の遅延の差。サービスメッシュを経由するHTTP・gRPC呼び出しなら、Istioの標準メトリクスistio_request_duration_millisecondsを送信側(reporter=source)と受信側(reporter=destination)に分けて比較 該当する場合 ゲームサーバーの処理時間は変わらないのにゲートウェイ区間の遅延だけが増え、その時刻にゲートウェイのCPUが飽和しているかRecv-Qがたまっている 該当しない場合 ゲートウェイを経由しない経路(直接接続、別のゲートウェイ)も同じように遅ければ、回線かゲームサーバー側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく サービスメッシュ(Istioなど)を使うと、サーバーごとに横に付くサイドカープロキシ(Envoy)も1段加わります。サービス間のリクエストは送信側のサイドカーと受信側のサイドカーを順に経由し、プロキシにログ・メトリクス収集などの機能を足すほど、処理時間と待ち時間が増えます。
実際の事例 Riot Games 2020: League of Legendsの欧州・ブラジルサーバーでのエッジホスト過負荷
出典7件
ID in-zone-transfer · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
別のエリアやダンジョンに入るとき、キャラクター情報を別のサーバーへ引き渡す過程で遅延や失敗が起きます。
なぜ ダンジョン入場や大陸移動で担当サーバーが変わる → すると 保存 → 転送 → 読み込み、移動先サーバーが混雑しているか空いているダンジョンインスタンスがなければ待機 → 画面では 長いロード、入場失敗、移動中の切断
症状 接続不可・無限ロード , フリーズ , 切断 , 引き戻し
要因 遅延, ストール
誰に起きるか 自分だけ, 特定の場所・チャンネル
いつ 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 引き継ぐデータの削減、移動先サーバーの事前予約、失敗時は元の場所へ戻す。
インフラチームの対応 ダンジョン・ゾーンサーバーの空きインスタンスの余裕を監視、ピーク前に台数を確保。
グラフでは 人数・負荷に連動して上昇 · ゾーン移動の所要時間・失敗数
確認箇所 サーバーが記録する引き継ぎの段階別所要時間(保存、転送、読み込み)と失敗理由、移動先サーバーの人数と空きインスタンス数 該当する場合 長いロード・入場失敗の報告があった時刻に引き継ぎ時間が延びるか失敗が集中し、移動先サーバーが混雑しているか空きインスタンスが尽きている 該当しない場合 引き継ぎはすぐ終わったのに到着後に止まるなら、密集エリア進入時のスポーン集中か、クライアントのロード側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく ロードなしでつながったシームレスワールドでも、サーバーの境界を越えるときに担当サーバーが変わります。境界付近で一瞬止まったり、引き戻しが起きたりすることがあります。
出典1件
カスケード障害 Cascading failure
ID in-cascade · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
1つのサービスが遅くなると、それを呼び出すサーバーが応答待ちで塞がり、関係のない機能まで止まります。
なぜ DB・認証など1つのサービスが遅くなる → すると 呼び出し側サーバーのスレッドと接続が応答待ちで塞がり、失敗したリクエストの再試行が負荷を上乗せ → 画面では 関係なさそうな機能まで、すべて遅くなるか止まる
症状 フリーズ , 入力遅延 , 接続不可・無限ロード
要因 ストール
誰に起きるか サーバー全体
いつ 人が集中したとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 すべての呼び出しにタイムアウト、サーキットブレーカー、機能ごとの隔離(バルクヘッド)、再試行は間隔を広げながら回数を制限、ヘルスチェックの応答は重い処理と分離。
インフラチームの対応 ロードバランサーのヘルスチェックが一時的に遅いだけのサーバーをすぐ外さないよう、失敗回数・間隔に余裕を持たせる、一度に外れるサーバー数の制限。
グラフでは 上限で頭打ち · サービスごとの応答時間・エラー率、スレッド・コネクションの使用数
確認箇所 サービスごとの応答時間・エラー率・再試行回数を時間軸をそろえて1画面に並べ、最初に遅くなった箇所を探す。ロードバランサーの後ろなら、ターゲットの応答時間(AWS ALBではTargetResponseTime)、ターゲットの5xx数(HTTPCode_Target_5XX_Count)、異常として外れたターゲット数(UnHealthyHostCount) 該当する場合 1つのサービスの遅延が先に上がり、続いてそのサービスを呼び出す側のスレッド・コネクション使用数が上限に張り付き、エラーがほかのサービスへ広がり、再試行回数と外れたターゲット数も一緒に増える 該当しない場合 複数のサービスが同じ瞬間に一斉に遅くなったなら、共用リソース(DB、ネットワーク、ホスト)の障害から確認 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく ヘルスチェック(生きているかを確認する検査)も連鎖を広げます。忙しいサーバーがチェックへの応答に遅れると、ロードバランサーが正常なサーバーを外してしまい、そのトラフィックが残りのサーバーに集中して次のサーバーも遅くなります。
実際の事例 Riot Games 2020: League of Legendsの欧州・ブラジルサーバーでのエッジホスト過負荷 Riot Games 2021: League of Legends EUWの5時間障害:補助的なDB一つでサーバー全体が停止 Roblox 2021: Robloxの73時間障害:サービスディスカバリ(Consul)クラスターでの競合 AWS 2021: AWS us-east-1の内部ネットワーク輻輳 AWS 2025: AWS us-east-1のDynamoDB DNS障害と長引いた復旧
出典4件
補助サーバーの障害 Auxiliary service outage
ID in-subservice · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
チャット・パーティ・オークションのように、ゲームサーバーとは別に動くサーバーで障害が起きると、その機能だけが動かなくなります。
なぜ 機能専用サーバーが遅くなるか落ちる → すると その機能のリクエストだけ応答なし → 画面では チャットができない、パーティ招待に反応なし、取引所が無限ロード(戦闘は正常)
症状 不発・ロールバック , 接続不可・無限ロード
要因 ストール, パケットロス
誰に起きるか 特定の機能だけ
いつ ときどきランダムに, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 失敗してもゲームは続けられる設計、機能ごとの状態表示、複数の機能を中央サーバー1台に集めない。
インフラチームの対応 補助サーバーごとのヘルスチェック・アラート、冗長化と自動再起動。
グラフでは 接続が一斉に切れる · 機能ごとのリクエスト成功率、補助サーバーの接続数・ヘルスチェック
確認箇所 チャット・パーティ・オークションなど補助サーバーごとのヘルスチェック・プロセス状態と接続数、機能ごとのリクエスト成功率・応答時間。ロードバランサーの後ろならターゲットグループのUnHealthyHostCount 該当する場合 報告された機能を担当するサーバーだけがヘルスチェック失敗や接続数の急落を示し、ゲームサーバーのティックと戦闘は正常 該当しない場合 複数の機能が一斉に止まったなら、それらの機能をまとめて中継する中央サーバーかカスケード障害側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく パーティ・ギルド・ささやき(ウィスパー)・サーバー間移動を1台の中央サーバー(ワールドサーバー・マネージャーサーバー)がすべて中継する構成では、そのサーバー1台が遅くなるだけで複数の機能が一斉に止まります。
出典3件
デプロイ・再起動 Deploy / rolling restart
ID in-deploy · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
アップデートのためにサーバーを再起動するとき、接続を移さずに止めると、そのサーバーにいた人は切断され、終了直前の保存と再接続が一気に集中します。
なぜ ホットフィックスのデプロイでサーバーを順番に再起動 → すると 接続を別のサーバーに移さずに終了、そのサーバーにいた全ユーザーの保存がDBに集中 → 画面では 告知なしの切断、再接続の殺到
症状 切断 , 接続不可・無限ロード , 入力遅延
要因 ストール
誰に起きるか サーバー全体, 特定の場所・チャンネル
いつ ときどきランダムに, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 ドレイン機能(新規接続だけを止め、既存のユーザーが抜けるまで待つ)、キャラクターを別のサーバーへ移す、終了前の保存を分散して行う、再起動後はキャッシュのロード・JITウォームアップを終えてから準備完了を通知、ホットリロードは別スレッドで先に読み込んでおき、ティックの合間に一度に差し替え。
インフラチームの対応 デプロイツールが1台ずつドレインを待ってから再起動、再起動したサーバーは準備完了(ウォームアップ完了)を確認してからトラフィックを受ける、デプロイ時刻の告知。
数値の目安 サーバー1台に5,000人いれば、終了直前の数秒間に5,000件の保存がDBに集中します。
グラフでは 接続が一斉に切れる · サーバーごとの接続数、DB書き込み数
確認箇所 デプロイツールの作業記録(サーバーごとの再起動時刻)を、接続数・切断数・DB書き込み・ログインリクエストのグラフに縦線(アノテーション)として重ねて確認 該当する場合 サーバーごとの接続数が再起動時刻に1台ずつ順番に急落し、その直前にDB書き込みが、直後にログインリクエストが跳ね上がる 該当しない場合 切断の時刻がデプロイ・再起動の記録と重ならなければ、サーバークラッシュかネットワーク機器側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 再起動した直後の数分間も遅くなります。キャッシュが空なのでDBへの問い合わせが集中し、Java・C#のサーバーは実行しながらコードを最適化する過程(JITウォームアップ)が終わる前なので、同じ処理により時間がかかります。サーバーを止めずにスクリプトやデータテーブルを読み直す方式(ホットリロード)でも、読み込み中はティックが止まるため、短い停止が起きます。
出典3件
ID in-autoscale · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
人が集中するとサーバーを自動で増やしますが、準備に数分かかり、その間は既存のサーバーが過負荷になります。
なぜ イベント開始で接続が急増 → すると 新しいサーバーが起動して準備が整うまで数分 → 画面では イベント開始直後の数分間、スローモーション・接続不可
症状 スローモーション , 接続不可・無限ロード
要因 ストール
誰に起きるか サーバー全体
いつ 人が集中したとき, 接続直後・メンテ明け
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 チャンネル分散(すでに混雑しているチャンネルにいる人は新しいサーバーに移せない)、新しいサーバーの起動・データロード時間の短縮。
インフラチームの対応 イベント前の事前スケールアウト、ウォームアップ済みの予備サーバー、縮小時は残っている人が抜けてから停止。
数値の目安 負荷の検知に1〜数分(メトリクスを数分間平均して見るため)、新しいサーバーを起動してゲームデータを読み込み、キャッシュを埋めるのにさらに数分。
グラフでは 接続直後・メンテ明けに急増 · インスタンス数、CPU使用率、接続待ち
確認箇所 オートスケーリングのアクティビティ履歴(スケールアウトを決めた時刻、新しいインスタンスがサービスに入った時刻)をCPU使用率・接続数のグラフに重ねて確認。AWSではAuto Scalingグループのメトリクス(有効にしないと表示されない)GroupDesiredCapacity(目標台数)・GroupPendingInstances(準備中)・GroupInServiceInstances(サービス中) 該当する場合 接続が急増してから数分間、目標台数と準備中のインスタンスだけが増えて既存サーバーのCPUが上限に張り付き、サービス中のインスタンスが増えた時刻から解消する 該当しない場合 新しいインスタンスが入った後も遅いなら、サーバー台数以外の原因(DBなどの共用リソース、カスケード障害)側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく オートスケーリングは主に、ログイン・ゲートウェイ・ダンジョンのように、新しいサーバーで新しい人を受け入れればよい所に使います。縮小するときにも問題が起きます。人が減った明け方にサーバーを減らすとき、残っている人が抜けるのを待たずに止めると、その人たちは切断されます。
実際の事例 AWS 2021: AWS us-east-1の内部ネットワーク輻輳 AWS 2025: AWS us-east-1のDynamoDB DNS障害と長引いた復旧
出典4件
ログ・監視の過負荷 Logging / monitoring overhead
ID in-monitoring · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
障害が起きるとログが急増し、ログを同期で送るサーバーはログのせいでさらに遅くなります。
なぜ エラー発生に伴い、ログ・メトリクスの送信量が急増 → すると ログコレクターが詰まり、同期送信するサーバーは待たされる → 画面では 障害時のカクつき・フリーズがログのせいでさらに悪化
症状 カクつき , フリーズ
要因 ストール
誰に起きるか サーバー全体
いつ 人が集中したとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲーム開発チームの対応 非同期送信、サンプリング、バッファがあふれたら破棄、同じエラーログはまとめて送る。
インフラチームの対応 ログコレクターの容量を障害時の急増量を基準に確保、コレクターの滞留アラート。
グラフでは 不定期なスパイク · ログ送信量、ログコレクターのキュー
確認箇所 サーバーの毎秒のログ行数・バイト数と、ログ収集エージェントのキュー・破棄数をティック時間と並べて確認。止まっているスレッドがあれば、bcc offcputime -pでログの書き込み・送信で待っているかを確認 該当する場合 ティックが跳ねた時刻にログ量が普段の数十倍に跳ね上がり、ゲームスレッドの待ち時間がログ書き込み・送信のコールスタックに集中している 該当しない場合 ログ量が普段と同じか、ゲームスレッドがログ側で待っていないなら、ログの急増は障害の結果にすぎないため、最初にエラーを出した原因を別に探す 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
サーバー間の時刻のずれ Clock skew between servers
ID in-clock-skew · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
サーバーごとに時計が少しずつずれていると、クールタイム・バフ・イベント開始の判定がサーバーごとに食い違います。
なぜ 時刻同期が止まったサーバーの時計が、ほかのサーバーと数百ms〜数秒ずれる → すると バフの終了時刻のような絶対時刻をサーバー間で受け渡すと判定が食い違う → 画面では 移動したらバフが消える、クールタイムがまた最初から始まる
症状 不発・ロールバック
要因 遅延
誰に起きるか 自分だけ
いつ 移動中・マップ切り替え時
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 サーバー間では絶対時刻の代わりに残り時間で受け渡す。
インフラチームの対応 時刻同期(NTP・chrony)の監視、サーバー間の時刻のずれのアラート。
数値の目安 時刻同期(NTP・chrony)が正常なら、同じデータセンターのサーバー同士では通常数ms以内です。同期が止まったり、仮想サーバーが長く停止してから再開したりすると、数百ms〜数秒に広がります。
グラフでは 徐々に上昇 · サーバーごとの時刻オフセット
確認箇所 サーバーごとにchronyc trackingのSystem time(システム時計とNTP時計の差)・Last offsetとRef time(時刻ソースの測定値を最後に反映した時刻)を集めて比較 該当する場合 問題のサーバーのオフセットがほかのサーバーより数百ms以上ずれているか、Ref timeがずっと前で止まっていて、判定の食い違いがそのサーバーを行き来する移動でだけ起きる 該当しない場合 すべてのサーバーのオフセットが数ms以内なら、ゲーム側の時間計算か、クライアントの時刻同期の誤差側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 1台のサーバーの時計が一気に前後へ跳ぶ現象は、サーバーOS層の「システム時刻のジャンプ(NTPステップ)」で扱います。
出典4件
ID in-bots · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
ボットは人よりはるかに頻繁にリクエストを送り、サーバーのスループットを食いつぶします。
なぜ 狩り・移動・取引を休まず繰り返すボットが大量に接続 → すると サーバーの処理量とDB負荷が増加 → 画面では 特定の狩場やサーバー全体が重くなる(スローモーション・入力遅延)
症状 スローモーション , 入力遅延
要因 ストール
誰に起きるか サーバー全体, 特定の場所・チャンネル
いつ 常に, 夜のピーク時間帯
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 ボット検知、アカウント・キャラクターごとのリクエスト頻度の制限。
インフラチームの対応 IPごとの接続・リクエスト頻度の制限(ネットカフェやモバイル回線は複数人が1つのIPを使うので余裕を持たせる)、ファイアウォール・WAFでボットのアドレス帯を遮断。
グラフでは 一部だけ高い · アカウント・IPごとの毎秒リクエスト数
確認箇所 ゲームサーバーのログで、アカウント・キャラクターごとの毎秒リクエスト数の分布と上位リストを確認。コード側のメトリクスがなければ、ファイアウォール・WAFのIPごとのリクエスト数 該当する場合 少数のアカウント・IPが人間には不可能な頻度で休みなくリクエストしており、それらを制限するとサーバー負荷が目に見えて下がる 該当しない場合 リクエストがアカウント間で均等に分散していれば、通常の人数増加側(ティックバジェット超過、オートスケーリングの遅れ) 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
外部サービスへの依存 External dependencies (auth, billing, platform)
ID in-external · 主担当 外部・外部 · 副担当 ゲーム開発チーム・サーバー開発
プラットフォームのログイン、決済、本人確認などの外部サービスが遅くなったり止まったりすると、その段階で先に進めなくなります。
なぜ 外部の認証・決済サービスの障害や遅延 → すると その段階で応答待ち → 画面では ログイン不可、決済失敗。すでにプレイ中の人は問題なし
症状 接続不可・無限ロード , 不発・ロールバック
要因 ストール
誰に起きるか サーバー全体, 特定の機能だけ
いつ 接続直後・メンテ明け, 特定の操作をしたとき
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 外部呼び出しにタイムアウトとわかりやすい案内、認証結果のキャッシュ、決済の再試行・補償手続き。
外部の対応 認証・決済・プラットフォームの事業者に障害の確認と復旧を依頼、ユーザーに外部サービスの障害であることを案内。
グラフでは ある時点から階段状に上昇 · 外部呼び出しの応答時間・エラー率、ログイン成功数
確認箇所 プラットフォームのログイン・決済・本人確認など外部呼び出しごとの応答時間・エラー率・タイムアウト数と、事業者のステータスページ 該当する場合 ログイン・決済の失敗が集中した時刻から、特定の外部呼び出しのエラー・タイムアウトだけが一段上がったまま推移し、事業者のステータスページに同じ時刻の障害が載っている 該当しない場合 外部呼び出しは正常なのにログインできないなら、ログインサーバー自体(スレッドプールの枯渇、DB)かOSの接続待ちキュー(backlog)側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
実際の事例 Fastly 2021: Fastly CDNで世界規模のエラー AWS 2021: AWS us-east-1の内部ネットワーク輻輳 AWS 2025: AWS us-east-1のDynamoDB DNS障害と長引いた復旧
出典3件
マッチメイキング・リージョン割り当ての誤り Wrong region assignment (matchmaking / GeoDNS)
ID in-region-match · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・ネットワークインフラ, 外部・外部
近いリージョンがあるのに遠いリージョンのサーバーに割り当てられると、回線に問題がなくても、そのユーザーだけPingが常に高くなります。
なぜ GeoIPデータの誤り、VPN、パーティメンバーの平均Pingでパーティ全体を割り当て、人数が足りないときに遠いリージョンまで広げるルール、DNSリゾルバーの位置を基準にした割り当て → すると 近いリージョンがあるのに、海の向こうのリージョンのサーバーに接続 → 画面では 複数のリージョンにサーバーを置いたゲームで、自分だけ(または自分のパーティだけ)Pingが常に高く、入力遅延・引き戻し・スキル不発
症状 入力遅延 , 引き戻し , 不発・ロールバック
要因 遅延
誰に起きるか 自分だけ, 特定の地域・ISP
いつ 常に, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・ネットワークインフラ, 外部・外部
ゲーム開発チームの対応 サーバー:GeoIPの代わりにクライアントが測定したリージョン別のPingで割り当て、遠いリージョンへ広げるルールにPingの上限を設ける、パーティは平均に加えて最も高いメンバーのPingも考慮、割り当てたリージョンとその時のPingをログに記録。クライアント:リージョン別のPingをUDPで測ってマッチングリクエストに添えて送る、接続中のリージョンとPingを画面に表示、リージョンを自分で選べる選択肢。
インフラチームの対応 DNSでリージョンを選ぶなら、権威DNSがEDNS Client Subnetに対応しているかを確認(ユーザーが使うリゾルバーが送らなければリゾルバーの位置で割り当てられる)、GeoIPデータベースの定期更新、リージョン別サーバーの接続ログにGeoIPの国・ASNを付けて、遠いリージョンへ行っている国・通信事業者を特定。
外部の対応 ユーザーにVPN・ラグ軽減ツールを切って再接続してみるよう案内、会社や海外のDNSを使うユーザーに通信事業者のDNSへ切り替えてみるよう案内、GeoIP事業者に誤った位置の訂正を依頼。
数値の目安 ソウルのユーザーが東京リージョンの代わりに米国西海岸リージョンに割り当てられると、Pingは約30msから約130msに増えます。GeoIPは国単位なら約99.8%当たりますが、都市単位では米国でも50km以内に収まる割合が約66%です。VPNを使うと、ユーザーの位置の代わりにVPNサーバーの位置が返ります。
グラフでは 一部だけ高い · ユーザーごとのRTT(Ping)、割り当てられたリージョンの分布
確認箇所 リージョン別サーバーの接続記録(ロードバランサーのアクセスログ、VPCフローログ)に残ったクライアントIPにGeoIPの国・ASNを付け、国・通信事業者ごとにどのリージョンに接続したかを集計。ユーザー1人なら、そのユーザーが実際に接続したリージョンと、近いリージョンまでのPing(ユーザーが測るか、そのリージョンのサーバーからユーザーのIPへmtr)を比較 該当する場合 RTTが高いユーザー・国が近いリージョンを使わずに遠いリージョンに接続しており、近いリージョンまで測ったPingは低い 該当しない場合 近いリージョンに正しく割り当てられているのにPingが高ければ、迂回ルーティングか、そのユーザーの回線・Wi-Fi側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく DNSでリージョンを選ぶ方式(位置情報・レイテンシベースのDNS)は、ユーザー本人の代わりに、ユーザーが使うDNSリゾルバーのアドレスを見て位置を推測します。ユーザーのアドレスの一部を伝えるEDNS Client Subnetにリゾルバーが対応していなければ、会社のDNSや遠くにあるDNSを使うユーザーは、リゾルバーのある場所を基準に割り当てられます。マッチングシステムも、パーティをメンバーのPingの平均で判断したり、待ち時間が長くなるとPingの基準を広げて遠いリージョンに割り当てたりします。AWS GameLift Serversも、パーティのPingのデフォルト基準は平均で、Pingの上限を50msから100ms、200msへと広げていく設定を例に挙げています。VPNを有効にしたユーザーは、中継サーバーを経由して増えた遅延(「VPN・ラグ軽減ツール経由」)と遠いリージョンへの割り当てが重なることがあるため、VPNを切って再接続したときに割り当てられるリージョンが変わるかどうかで切り分けます。近いリージョンがそもそもなく、遠いリージョンに接続する場合は「伝搬遅延(物理的な距離)」で扱います。
出典8件
TLS証明書の期限切れ・設定ミス TLS certificate expiry / misconfiguration
ID in-cert · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ログイン・API・アップデートサーバーの証明書が期限切れになったり中間証明書が抜けていたりすると、その瞬間から新たに接続するクライアントのTLS接続が失敗します。
なぜ 証明書の有効期限が切れている、サーバーが中間証明書を含めずに送っている、またはユーザー端末の日付・時刻がずれている → すると クライアントが証明書の検証に失敗し、TLS接続を切断 → 画面では ログイン・アップデートの段階で接続不可・無限ロード、ショップなどHTTPSの機能だけ失敗。すでに接続していた人はたいてい問題なし
症状 接続不可・無限ロード , 不発・ロールバック
要因 ストール
誰に起きるか サーバー全体, 特定の機能だけ, 自分だけ
いつ 接続直後・メンテ明け, 特定の操作をしたとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 証明書エラーをほかの接続失敗と区別できるエラーコードで記録して案内、日付のずれが原因なら端末の日付・時刻を自動設定にするよう案内、証明書ピンニング(pinning)を使うなら予備の鍵も一緒に組み込み、証明書の差し替え日程をインフラチームと合わせる。
インフラチームの対応 ネットワーク:ロードバランサー・CDNでTLSを終端する場合、マネージド証明書の自動更新の状態と残り日数のアラート(ACMではDaysToExpiry)、検証用DNSレコードの維持。サーバー機器・OS:サーバーでTLSを終端する場合、更新の自動化と更新後の設定の再読み込み、中間証明書まで含めたチェーンで設定、ログイン・API・アップデートの各アドレスについて残りの有効期間を外部から定期的に検査してアラート。
数値の目安 Let’s Encryptの証明書は有効期間が90日で、60日ごとの更新が推奨されています。AWS Certificate Managerは、DNSで検証した証明書を期限の45日前に確認して自動更新します。自動更新が気づかれないまま失敗すると、ちょうど期限の時刻に新規接続が一斉にできなくなります。
グラフでは 接続が一斉に切れる · ログイン成功数、TLSハンドシェイクのエラー数
確認箇所 openssl s_client -connect HOST:443 -showcertsでサーバーが実際に送る証明書の一覧を確認し、各証明書の有効期限(notAfter)をopenssl x509 -noout -enddateで確認。ロードバランサーでTLSを終端しているなら、TLSネゴシエーションのエラー数(AWS ALB・NLBではClientTLSNegotiationErrorCount)とログイン成功数 該当する場合 有効期限が過ぎているか、サーバーが送った一覧に中間証明書が含まれておらず、エラーが増え始めた時刻が期限の時刻か証明書を差し替えた時刻と重なる 該当しない場合 証明書の一覧と有効期限が正常なのに一部のユーザーだけ失敗するなら、そのユーザー端末の日付・時刻か、古いOSのルート証明書リストを確認 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 中間証明書が抜けた設定は、PCのブラウザで開くと問題なく見えることがあります。ブラウザはほかのサイトで受け取った中間証明書を覚えていて欠けた部分を補いますが、Androidアプリのようにその記憶を持たないクライアントは失敗します。有効期間も短くなりつつあります。Let’s Encryptはデフォルトの有効期間を2027年に64日、2028年に45日へ短縮する予定で、60日ごとに更新するよう固定した設定では、64日の証明書だと余裕が4日しかなく、45日の証明書では期限を過ぎてしまいます。AWS Certificate Managerも、インポートした証明書は自動更新せず、検証用のDNSレコードを消すと更新に失敗します。ログインできなくなる様子は「DNSの障害・遅延」と似ていますが、証明書の問題はサーバーのアドレスを解決した後のTLSハンドシェイクで失敗し、始まった時刻が期限の時刻や証明書を差し替えた時刻と重なります。
出典12件
ID in-login-queue · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
リリース直後やメンテ明けに接続が集中すると、ログイン待機列が上限に達して新たな待機を拒否し、待っていたユーザーは一瞬切れた間に順番を失って最後尾に戻されます。
なぜ ログインサーバーが一度に受け付けられる人数より接続しようとする人が多いため待機列を設け、長くなりすぎるとサーバーを守るために新たな待機を拒否 → すると 待機列が長いほど待ち時間が延び、その間にWi-Fi・モバイル回線が一瞬途切れただけで順番を失う → 画面では 接続不可・無限ロード、待機中にエラーが出てゲームが終了、また最後尾から待ち直し
症状 接続不可・無限ロード , 切断
要因 ストール
誰に起きるか サーバー全体, 自分だけ
いつ 接続直後・メンテ明け, 夜のピーク時間帯
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
ゲーム開発チームの対応 サーバー:待機列の上限をログインサーバーが実際に処理できる量に合わせる、待機中に切れたユーザーの順番を一定時間確保(再接続猶予)、順番と予想待ち時間の表示、待機列の長さ・拒否数・待機中の切断数をメトリクスとして記録。クライアント:待機中に切れてもゲームを終了せず同じ順番へ自動で再接続、再試行間隔は指数バックオフとジッターで分散。
インフラチームの対応 サーバー機器・OS:リリース前の負荷試験でログイン・ロビーサーバーの処理上限を測定、リリース時は予備機をすぐ追加できるよう準備、待機列のメトリクスを接続試行数と同じグラフで確認。
数値の目安 2021年のFINAL FANTASY XIV拡張パッケージのリリース時には、論理データセンターごとに待機人数が17,000人を超えると新たな待機を拒否していました(Error 2002)。待機中に接続が切れた場合はロビーサーバーが数十秒〜1分待ち、その間に再接続すれば待機列の途中から再開できるようにしていました。
グラフでは 上限で頭打ち · ログイン待機列の長さ、上限到達による拒否数、待機中の切断数
確認箇所 ログイン・ロビーサーバーが記録する待機列の長さ、平均待ち時間、上限到達による拒否数、待機中の切断数を、接続試行数と同じグラフに並べて確認 該当する場合 リリース直後・メンテ明けに待機列の長さが上限で頭打ちになっている間に拒否数が増え、待機中の切断がWi-Fi・モバイル回線のユーザーに集中 該当しない場合 待機列は短いのにログインが遅いなら、DB(db-login-storm)かOSの接続待ちキュー(so-backlog)側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく ログインが集中してDBが遅くなるケースは「ログイン殺到とN+1クエリ」、OSの接続待ちキューがあふれるケースは「接続待ちキュー(backlog)のあふれ」で扱います。この項目は、ゲームが意図的に設けるログイン待機列の設計の問題です。待機列の上限はログインサーバーを守る安全装置なので、なくせません。あふれたリクエストを早めに拒否してこそ、処理できるリクエストを処理し続けられるからです。その代わり、拒否や切断がユーザーに与える不利益を減らすことが肝心です。待機列が長くなるほど、Wi-Fi・モバイル回線のように回線が不安定なユーザーにエラーが集中します。
実際の事例 Square Enix 2021: FINAL FANTASY XIVの拡張パッケージ発売時の混雑とログイン待機列のエラー
出典2件
同期設計
原因16件 · メインページの章
ID sy-request-response · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ボタンを押しても、サーバーの応答が来るまでアニメーションも音も出ません。Pingがそのまま反応速度になります。
なぜ スキル・移動・アイテム拾いを、サーバーの確認が来てから再生 → すると 押した瞬間から、往復時間 + ティック待ちの間まったく反応なし → 画面では Pingが150msなら、すべての行動が0.2秒ずつ遅れてもっさりする
症状 入力遅延
要因 遅延
誰に起きるか 自分だけ
いつ 常に, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:アニメーション・音・エフェクトは押した瞬間に開始(先行演出)、結果(ダメージ・報酬)だけをサーバーの確定後に表示、移動・通常攻撃は予測してすぐに反映、サーバーから位置の補正を受けたら、その位置からまだ確認されていない入力を適用し直す。サーバー:受け取った入力で移動を自ら計算し、クライアントが予測した位置との差が基準を超えたときだけ補正値を送る。
数値の目安 反応時間 ≈ Ping + ティック間隔の半分 + 1フレーム。1秒20ティック・Ping 150msなら約190ms。
グラフでは 最初から常に高い · 入力から演出開始までの時間、RTT(Ping)
確認箇所 開発ビルドのクライアントログにボタン入力の時刻、最初のアニメーション・音の開始時刻、サーバー応答の到着時刻を記録し、ゲーム内のRTTと並べて確認。エンジンのネットワークエミュレーション(Unreal NetEmulation.PktLag)や試験サーバーのLinux tc netemで遅延を加え、Pingを変えながら測定 該当する場合 演出の開始が常にサーバー応答の到着と同じ瞬間で、入力から演出までの時間がRTT + ティック待ちの分あり、加えた遅延の分だけそのまま延びる 該当しない場合 演出は押した瞬間に始まり、ダメージの数字などの結果だけが遅れるなら正常な設計。Pingが低い環境でもティック間隔以上遅れるなら、二重のティック待ちかクライアントのフレームの問題 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく ターン制、カード、放置系のように速い反応が必要ないゲームでは、この方式が最も単純で安全です。問題になるのは、リアルタイムの操作があるゲームで、移動や通常攻撃までこの方式で作った場合です。
出典5件
逐次往復の多いプロトコル(chatty) Chatty protocol / sequential round trips
ID sy-chatty · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
1回の操作でサーバーとの往復が順番に何回も必要になると、Pingがその回数分だけ積み重なります。
なぜ ショップを開く → 一覧を要求 → 価格を確認 → 購入 → インベントリ更新を、それぞれ別々にリクエスト → すると 前のリクエストの応答を受け取ってから次のリクエストを送る → 画面では Ping 150msで1回の購入に1秒近くかかる。ロードがやけに長い
症状 入力遅延 , 接続不可・無限ロード
要因 遅延
誰に起きるか 特定の機能だけ, 自分だけ
いつ 特定の操作をしたとき, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:複数の段階を1回のリクエスト・レスポンスにまとめるようプロトコルを変更(例:購入の応答に更新後のインベントリを含める)。クライアント:必要なデータを先に受け取っておく、結果を待たないUI。
数値の目安 かかる時間 ≈ 往復回数 ×(Ping + サーバー処理 + ティック待ち)。5回ならPing 150msで約0.85〜1秒。
グラフでは 最初から常に高い · 機能ごとの完了時間、1回の操作あたりの往復回数
確認箇所 サーバー側のパケットキャプチャ(Wireshark)で、試験アカウントでショップでの購入・ログインなどの操作を1回行う間に、リクエストとレスポンスが何回交互にやり取りされるかとその間隔を数える。サーバーのリクエストログがあれば、セッションIDでまとめてリクエスト数と、リクエストごとの到着・応答時刻を確認 該当する場合 1つの操作でリクエストが前の応答を待ってから順番に何回もやり取りされ、完了時間がおおよそ往復回数 × RTTで、Pingが高い地域のユーザーほど同じ機能が比例して遅い 該当しない場合 往復は1〜2回なのに1つの応答に時間がかかるなら、サーバー処理・DB側の原因。Pingに関係なく全ユーザーが同じように遅いなら、サーバー負荷を確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典1件
スキルの先行入力なし No input/spell queue
ID sy-no-queue · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
前のスキルがサーバーで終わったという確認を受けるまで次のスキルを押せないと、連携のたびに往復時間が挟まります。
なぜ 次のスキル入力を「前のスキルの確定後」にだけ受け付ける → すると スキルとスキルの間に、毎回Pingの分だけ空白の時間ができる → 画面では 連携の間に毎回すき間ができ、Pingが高いほどDPSが下がる
症状 入力遅延 , 不発・ロールバック
要因 遅延
誰に起きるか 自分だけ, 特定の機能だけ
いつ 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:クールタイムが終わる前の一定時間(例:0.3〜0.4秒)以内の入力も受け付けてすぐサーバーへ送る、先行入力の受付時間。サーバー:少し早く届いた入力を拒否せず、クールタイムが終わった瞬間に実行。
数値の目安 クールタイム1秒の連携でPingが150msなら、スキルの間が毎回0.15秒以上空き、同じ時間に使えるスキルが13%以上減ります。
グラフでは 最初から常に高い · スキル間の空白時間、RTT(Ping)
確認箇所 サーバーログに、キャラクターごとのスキルのクールタイムが終わった時刻、次のスキルのリクエストが届いた時刻、実行時刻を記録し、その間の空白時間をユーザーのRTTと比較 該当する場合 クールタイムが終わってから次のスキルが実行されるまで常にRTT程度の空白があり、Pingが高いユーザーほど空白時間が長く、同じ時間に使ったスキル数が少ない 該当しない場合 空白時間がPingに関係なく一定なら、共通クールタイム(GCD)やアニメーションの長さの設計。空白時間がときどきだけ大きく跳ねるなら、ジッター・パケットロスかティックバジェット超過を確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく たとえばWorld of Warcraftは先行入力の受付時間を設け、プレイヤーが設定で調整できるようにしました。受付時間が往復時間より長ければ、連携の間にPingがほとんど挟まりません。
出典1件
Pingに削られる短い判定の受付時間 Timing window too short for latency + reaction
ID sy-short-window · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
回避・パリィ・ガードのように反応すべき時間が短いと、Pingがその時間を削ってしまい、よけられない攻撃が生まれます。
なぜ ボスの攻撃の予兆0.5秒、パリィの判定0.2秒のような短い判定の受付時間 → すると 予兆を見るのが遅れ(下りの遅延 + 補間)、自分の入力も遅れて届く(上りの遅延 + ティック待ち) → 画面では 確かによけたのに当たる、パリィが不発になる
症状 不発・ロールバック , 入力遅延
要因 遅延
誰に起きるか 自分だけ, 特定の機能だけ
いつ 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
ゲーム開発チームの対応 サーバー:攻撃の予兆をサーバー時刻で予約して前もって送る、判定の受付時間をPingの分だけ延ばす(ラグコンペンセーション)。クライアント:受け取った予兆を予約されたサーバー時刻に合わせて再生。
インフラチームの対応 ユーザーが多い地域の近くにサーバーを配置(地域サーバー)し、Ping自体を減らす。
数値の目安 Ping 150ms、補間100msなら、予兆が自分の画面に出るまで約0.18秒、自分の入力がサーバーに届くまで約0.1秒かかります。人の反応時間0.25秒を足すと、0.5秒の予兆に反応するのはほぼ不可能です。
グラフでは 一部だけ高い · 回避・パリィの失敗率(Ping帯別)
確認箇所 サーバーログに判定の受付時間の開始・終了時刻、ユーザー入力のサーバー到着時刻、そのユーザーのRTTを記録し、失敗率をPing帯(例:50ms刻み)ごとに分けて確認 該当する場合 Pingが高い帯ほど失敗率がはっきり高く、失敗した入力が受付時間の終了から少し後(RTTと補間時間を足した値以内)に届いている 該当しない場合 Ping帯に関係なく失敗率が同程度なら、攻撃パターンの難易度の問題。入力が受付時間内に届いているのに失敗と出るなら、判定コードかサーバー側の検証を確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID sy-no-lagcomp · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが「今のサーバー上の位置」だけで命中を判定すると、自分が見た画面と判定が食い違います。
なぜ 自分の画面の相手は約0.2秒前の位置(Ping 150ms、補間100msの場合) → すると サーバーは現在位置で判定するため、自分が狙った場所にはもういない → 画面では 確かに当てたのに外れる。動く対象には偏差撃ちが必要
症状 不発・ロールバック
要因 遅延
誰に起きるか 自分だけ
いつ 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:攻撃者が見ていた時点に巻き戻して判定(ラグコンペンセーション)、またはターゲット指定方式に変更。クライアント:攻撃時に自分が見ていた時点(補間中のサーバー時刻)も一緒に送る。
グラフでは 一部だけ高い · 動く対象への命中率(Ping帯別)
確認箇所 サーバーの判定ログに、攻撃時刻、攻撃者の画面上の対象位置(クライアントが送った値)、判定に使ったサーバー上の対象位置、攻撃者のRTTを一緒に記録。開発ビルドでサーバーが判定に使った位置をクライアント画面に重ねて描くと、すぐにわかる 該当する場合 外れた判定での2つの位置の差がおおよそ対象の速度 ×(攻撃者のRTT + 補間時間)で、Pingが高いほど動く対象の命中率だけが下がる 該当しない場合 止まっている対象にも外れるなら、ヒットボックス・衝突判定の問題。巻き戻しをしているのに食い違うなら、クライアントが補間時間をサーバーに誤って伝えていないかを確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID sy-lagcomp-overreach · 主担当 ゲーム開発チーム・サーバー開発
攻撃者を基準に巻き戻しすぎると、撃たれる側はもう隠れたのに当たります。
なぜ Pingが高い攻撃者のために、サーバーが大きく巻き戻して判定 → すると 撃たれる側の画面では、すでに遮蔽物に隠れた後 → 画面では 「壁の後ろで撃たれた」、Pingが高い人が有利
症状 不発・ロールバック
要因 遅延
誰に起きるか 自分だけ, 特定の地域・ISP
いつ 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 巻き戻しの上限を設ける(例:200〜250ms)、それよりPingが高い攻撃者は上限まで巻き戻し、残りは自分で偏差撃ちさせる。
グラフでは 一部だけ高い · 命中ごとの巻き戻し時間(攻撃者のPing別)
確認箇所 サーバーの判定ログに、命中ごとの巻き戻し時間、攻撃者のRTT、撃たれる側が遮蔽物に入ったサーバー時刻を記録。開発ビルドで巻き戻したヒットボックスを画面に描いてみる(Sourceエンジンではsv_showlagcompensation) 該当する場合 「壁の後ろで撃たれた」という報告の命中が巻き戻し時間の長い攻撃者に集中し、巻き戻し時間が上限なく攻撃者のPingに合わせて延びている 該当しない場合 巻き戻し時間が短い命中でも壁の後ろでの被弾が起きるなら、ヒットボックス・衝突判定の問題。撃たれる側のPingが高いなら、その人の移動がサーバーに遅れて届いたために起きたこと 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく 巻き戻しによる判定は「撃った側優先」です。撃たれる側が自分の画面ですでに安全な場所に入っていたなら巻き戻さない、「撃たれる側優先」の例外も提案されています。
出典3件
クライアント権威型 Client-authoritative results
ID sy-client-auth · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
それぞれが自分の結果を決めると、自分の画面は快適ですが、ほかの人の画面と結果が食い違い、チートにも弱くなります。
なぜ 位置・命中をクライアントが決め、サーバーは中継するだけ → すると 2人が互いに自分が先に当てたと主張し、サーバーは検証できない → 画面では 相手がワープ・壁抜け、「自分は当てたのに当たっていない」
症状 ワープ , 不発・ロールバック
要因 遅延
誰に起きるか サーバー全体
いつ 常に
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:重要な結果(命中など)は自ら検証、移動は速度・距離をチェック。クライアント:サーバーが拒否・補正した結果を受け取ったら、その値に戻す。
グラフでは 最初から常に高い · ありえない移動速度・食い違う命中報告の数
確認箇所 サーバーで、クライアントが報告した位置・命中をそのまま記録しておき、連続する位置報告から移動速度を計算して、最大速度を超える報告と、2人が互いに先に当てたという報告を数える 該当する場合 サーバーが報告を検証せずにほかのクライアントへ中継しており、ありえない速度や互いに食い違う命中報告が、アップデート・地域に関係なく継続的に出る 該当しない場合 サーバーが結果を自ら計算・検証しているなら、この原因ではない。その場合のワープはパケットロスか補間バッファ側を確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID sy-lockstep · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
全員が同じターンを一緒に計算する構造では、1人の入力が遅れると全員が待たされます。
なぜ ターンごとに全プレイヤーの入力がそろわないと計算できない → すると 1人の入力がジッター・パケットロスで遅れて到着 → 画面では 全員が同時に一瞬止まり、ひどいと「プレイヤーを待っています」ウィンドウ
症状 フリーズ , カクつき , 入力遅延
要因 ジッター, パケットロス, ストール
誰に起きるか 特定の場所・チャンネル
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:入力遅延をPingに合わせて自動調整、遅れている人だけを一時的に切り離し、残りは待たずに進行。クライアント:決められた入力遅延を適用、中継サーバーのないP2Pなら、入力遅延の調整と遅れている人の処理もホストのクライアントが担う。
数値の目安 入力遅延を「入力が相手に届く時間 + ジッター」より短く設定すると、停止が頻発します。届く時間は、直接やり取りするならPingの半分、中継サーバーを経由するなら2人のPingを足した値の半分ほどです。
グラフでは 不定期なスパイク · ターンの待ち時間、プレイヤーごとの入力到着の遅れ
確認箇所 ターンごとにプレイヤー別の入力到着時刻と、ターンが止まって待った時間を記録し、止まったターンで誰の入力を待っていたかを確認。中継サーバーがあれば、サーバー側のパケットキャプチャでプレイヤー別の入力パケットの到着間隔からも確認できる 該当する場合 止まったターンのたびに同じ1人の入力が入力遅延より遅れて到着しており、その時刻にその人のジッター・パケットロスが跳ねている 該当しない場合 入力はすべて時間どおりに届いているのに止まるなら、最も遅いPCの計算時間かサーバー処理の問題。止まらずに2つの画面の結果だけが食い違うなら計算結果のずれ(desync)なので、コマンド同期の経路計算の不一致を確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID sy-rollback · 主担当 ゲーム開発チーム・クライアント開発
相手の入力を予測して先に見せ、外れたら巻き戻して計算し直します。Pingが大きいほど巻き戻す幅が大きくなります。
なぜ 相手が入力を変える(予測と違う) → すると 実際の入力がPingの半分だけ遅れて届き、その分を巻き戻して再計算 → 画面では 相手の動きが数フレーム飛んだり、急に変わったりする
症状 ワープ
要因 遅延, ジッター
誰に起きるか 自分だけ
いつ 特定の操作をしたとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 入力遅延を1〜3フレーム組み合わせて巻き戻し幅を減らす、巻き戻しの上限を設ける。
数値の目安 Ping 100ms(片道50ms)なら、60fpsで約3フレーム巻き戻します。入力遅延を2フレーム設けると1フレームに減ります。
グラフでは 不定期なスパイク · 巻き戻したフレーム数、RTT(Ping)
確認箇所 クライアントが巻き戻しのたびに、巻き戻したフレーム数、その時のRTT、入力遅延の設定、巻き戻し・再計算にかかった時間を記録 該当する場合 相手の動きが飛んだという瞬間に巻き戻したフレーム数が大きく、平均の巻き戻し幅がおおよそ(片道遅延 − 入力遅延)÷ フレーム時間で、Pingが大きいほど大きくなる 該当しない場合 巻き戻し幅が小さいのにカクつきが起きるなら、再計算が1フレームの時間を超える性能の問題。巻き戻した後も2つの画面の結果が食い違い続けるなら計算結果のずれ(desync) 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
タイムスタンプなしの受信即時再生 Events played on arrival (no timestamps)
ID sy-no-timestamp · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
サーバーのイベントに発生時刻を付けず、受け取ったらすぐに再生すると、ネットワークのジッターがそのまま演出のタイミングのばらつきになります。
なぜ 「攻撃開始」「エフェクト再生」のイベントを届いた瞬間に実行 → すると パケットごとに到着時間が違うため、間隔がばらつく → 画面では 連続攻撃のモーションが速くなったり遅くなったりし、ボスの攻撃パターンのタイミングが毎回違う
症状 カクつき , 早送り
要因 ジッター
誰に起きるか 自分だけ
いつ 常に
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:イベントに付いた時刻に合わせて再生(イベント予約・補間バッファ)。サーバー:イベントに発生時刻(サーバー時刻)を付けて送る。
グラフでは 不定期なスパイク · イベントの再生間隔、パケットの到着間隔
確認箇所 サーバーログのイベント発生時刻と、クライアントログの到着・再生時刻をイベント番号で突き合わせて間隔を比較。開発ビルドでジッターを加えて(tc netemのジッター値、Unrealのネットワークエミュレーションの最小・最大遅延)再現してみる 該当する場合 サーバーでの発生間隔は一定なのに、再生間隔が到着間隔をそのままなぞってばらつく 該当しない場合 到着間隔はそろっているのに再生がばらつくなら、クライアントのフレームの問題(フレームタイムのスパイク)。サーバーでの発生間隔からぶれているならティックバジェット超過 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典5件
二重のティック待ち Double tick quantization
ID sy-double-tick · 主担当 ゲーム開発チーム・サーバー開発
リクエストを次のティックまでためてから処理し、結果もその次のティックで送ると、ティック間隔が2回分加わります。
なぜ 受け取ったリクエストは次のティックで処理 → すると 処理結果も次の送信ティックにまとめて送る → 画面では 回線のPingは低いのに、反応がティック間隔の1.5倍ほど一定に遅れる。10ティックのサーバーなら平均0.15秒、最悪0.2秒
症状 入力遅延
要因 遅延
誰に起きるか サーバー全体
いつ 常に
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 処理したティックですぐ応答を送る、ティックレートを上げる、重要な応答は即時送信。
数値の目安 10ティックのサーバーは1ティックが100msなので、ティック待ちだけで平均150ms、最悪200msが加わります。待つのが1回だけなら平均50msです。
グラフでは 最初から常に高い · リクエスト到着から応答送信までの時間
確認箇所 サーバー側のパケットキャプチャで、試験アカウントが同じ行動(例:アイテム使用)を何回か行うとき、リクエストパケットが届いた時刻とその応答パケットが出た時刻の間隔を測る。サーバーログがあれば、リクエスト到着時刻、処理したティック番号、応答を送った時刻を確認 該当する場合 サーバー内でかかった時間が平均でティック間隔の1.5倍、最大で2倍ほどで、RTTに関係なく一定 該当しない場合 サーバー内の時間が平均でティック間隔の半分前後なら、ティック待ちは1回だけ。ティック間隔よりばらついて長いならティックバジェット超過を確認 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
厳しすぎるサーバー検証 Over-strict server validation
ID sy-strict-check · 主担当 ゲーム開発チーム・サーバー開発
移動速度・クールタイム・射程をサーバーが厳しくチェックしすぎると、ジッターでまとめて届いた正常な入力まで拒否します。
なぜ 「1ティックで移動できる距離」「クールタイムの許容誤差0ms」のような厳しい基準 → すると ジッターで2つのコマンドが1ティックにまとめて届くと、ルール違反と判定 → 画面では 引き戻し、クールタイムが終わったのにスキルが拒否される
症状 引き戻し , 不発・ロールバック
要因 ジッター
誰に起きるか 自分だけ
いつ ときどきランダムに, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 累積の許容量(トークンバケット)方式でチェック、Ping・ジッターの分の余裕を持たせる。
グラフでは 不定期なスパイク · サーバー検証による拒否・位置補正の数
確認箇所 サーバーログに、検証による拒否・位置補正のたびに、理由、そのティックに届いたそのユーザーのコマンド数、直前のコマンドとの到着間隔を記録 該当する場合 拒否・補正が、1ティックにコマンドが2つ以上まとめて届いた瞬間に集中しており、数秒単位で合計した移動量・使用回数はルールの範囲内 該当しない場合 数秒単位で合計してもルールを超えるなら、実際の速度超過・チートの可能性。拒否が特定の通信事業者と夜の時間帯に集中するなら、特定の通信事業者のユーザーに集中する検証の誤検知側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
ホスト(部屋主)型の構成 Listen server / host advantage
ID sy-host · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
1人のプレイヤーのPCがサーバーの役割をすると、その人の回線とPC性能が全員の体感を決めます。
なぜ ホストのPCがサーバーの役割を担う(P2P、リッスンサーバー) → すると ホストの回線やPCが遅いと全員に波及、ホスト自身はPing 0 → 画面では ホストだけが有利、ホストが抜けると全員がフリーズ・切断
症状 カクつき , フリーズ , 切断
要因 遅延, ストール
誰に起きるか 特定の場所・チャンネル
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
ゲーム開発チームの対応 サーバー:判定を担う専用サーバーへ移行、それまではマッチング時に回線・PCの良い人をホストに選ぶ。クライアント:ホストの移行(マイグレーション)に対応、マッチング時にほかの参加者とのPing・上り速度・PC性能を測定して送る。
インフラチームの対応 専用サーバー用のサーバー機器・インスタンスを確保、ユーザーが多い地域の近くに配置。
グラフでは 一部だけ高い · ホストごとのラグ報告・切断数
確認箇所 マッチログに、ホストの上り速度、参加者ごとのホストとのRTT、ホストPCのフレーム時間、ホストが抜けた時刻を記録し、ラグ・切断の報告をホストごとにまとめて確認。ユーザー側でも、同じメンバーでホストだけ替えてもう一度プレイすれば確認できる 該当する場合 ラグ・切断が特定のホストの部屋に集中し、そのホストの上り速度が低いときやフレーム時間が長いときに参加者全員が一緒に悪化し、ホストの移行がなければホストが抜けた瞬間に全員が切断される 該当しない場合 ホストに関係なく同じ地域の参加者だけが悪いなら、回線・経路の問題。専用サーバー構成なら、この原因ではない 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
先行演出後のサーバー拒否 Client-side feedback rejected by server
ID sy-optimistic-reject · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
自分の画面で先に見せたヒット・スキルを後からサーバーが認めないと、確かに見た結果がなかったことになります。
なぜ ヒットエフェクト・スキルモーションをサーバーの確認前に先に再生(先行演出) → すると サーバーが射程・対象の位置・クールタイム・リソースを改めてチェックして拒否 → 画面では 血しぶきが出たのにダメージなし、スキルのモーションだけ出て効果なし、クールタイムだけ回る
症状 不発・ロールバック , 引き戻し
要因 遅延
誰に起きるか 自分だけ, 特定の機能だけ
いつ 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:ダメージの数字・死亡・報酬など確定が必要な部分だけサーバーの結果で表示、よくある拒否理由は先にチェック、拒否されたらクールタイム・リソースを元に戻して理由を表示。サーバー:射程・対象位置のチェックにPingの分の余裕を持たせる、拒否の応答に理由を含めて送る、スキルごとの拒否率をメトリクスとして収集。
数値の目安 拒否の応答は、押してからPing + ティック待ちの分だけ遅れて届きます。Ping 150msなら、約0.2秒の間「当たった」と思い込みます。
グラフでは 一部だけ高い · スキルごとのサーバー拒否率(Ping帯別)
確認箇所 サーバーで、スキルごとの拒否率と拒否理由(射程、対象位置、クールタイム、リソース)を集め、ユーザーのRTT帯別に分ける。クライアントには、先行演出した行動が拒否された回数を記録 該当する場合 拒否が特定のスキルと射程・対象位置の理由に集中し、Pingが高いほど拒否率が上がる 該当しない場合 拒否理由がクールタイム・リソースでPingと関係ないなら、クライアントとサーバーのデータ値(クールタイム、コスト)が違っていないかを確認。拒否はなく、演出がサーバー応答の後にしか始まらないなら、サーバー応答後にだけ演出(リクエスト・レスポンス方式) 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく 先行演出はPingを隠す最もよい方法です。ただし、クライアントとサーバーが判断に使う情報(相手の位置、残りのリソース)が違うほど、拒否が増えます。スキルごとの拒否率をメトリクスとして集めておくと、判定が食い違う箇所を見つけやすくなります。
出典2件
コマンド同期の経路計算の不一致 Command sync with divergent pathing
ID sy-path-mismatch · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
「ここへ行け」だけをやり取りして経路は両側でそれぞれ計算すると、計算が少し違うだけで、キャラクターやモンスターが別の経路を進んだ後、元の位置に引き戻されます。
なぜ クリック移動・モンスターの追跡で目的地だけを送り、経路はクライアントが別途計算 → すると 地形データの違い、ほかのキャラクターとの衝突、計算順序の違いで、サーバーと別の経路を移動 → 画面では モンスターが壁をすり抜けて進んだ後にパッと位置が移る、クリックしたキャラクターが滑るように向きを変える
症状 ワープ , 引き戻し
要因 遅延
誰に起きるか 特定の場所・チャンネル, 自分だけ
いつ 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:経路の中間地点(ウェイポイント)も一緒に送る、定期的に位置を合わせる。クライアント:ずれはなめらかに収束させる、サーバーと同じ地形データを使う。
グラフでは 不定期なスパイク · オブジェクトごとの位置補正の回数・距離
確認箇所 サーバーが送った位置とクライアントが計算した位置の差をオブジェクトごとに記録し、補正が起きた座標をマップ上にプロットしてみる。両側の経路の結果や位置をチェックサムにまとめて定期的に比較すれば、ずれ始めた時点を見つけられる 該当する場合 補正が特定の地形(段差、狭い通路、坂)や混雑した場所に集中し、ネットワークのメトリクスが正常なユーザーでも同じ場所で繰り返し起きる 該当しない場合 場所に関係なく、パケットロス・ジッターが跳ねた瞬間にだけ補正されるなら回線の問題。1匹のモンスターが複数の人の画面で同時に飛ぶなら、モンスターの制御権が遅いクライアントにないかを確認 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく クリック移動・タブターゲットのゲームがPingに鈍感な理由の1つがこの方式です。その代わり両側の結果が同じになる保証がないので、ときどき位置を合わせる仕組みが欠かせません。浮動小数点演算は、CPUの種類、コンパイラとその最適化設定(デバッグビルドとリリースビルドの違いを含む)によって結果がわずかに変わることがあります。ロックステップ・ロールバックのように入力だけをやり取りし、両側の計算結果がまったく同じだと仮定する構造では、この小さな差が積み重なり、2つの画面のゲーム状態が分かれてしまうずれ(desync)が起きることがあります。
出典6件
ID sy-low-send-rate · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが位置の更新(スナップショット)を1秒に数回しか送らないと、その分だけ補間バッファを長く取る必要があり、ほかのキャラクターをより遠い過去の姿で見ることになります。
なぜ 送信量を節約するため、位置の更新を1秒に5〜10回しか送らない → すると なめらかに描くにはバッファをパケット間隔の2倍(200〜400ms)取る必要があり、短くするとパケットを1つ落としただけで止まる → 画面では 相手の方向転換が遅れて見え、判定と食い違う。バッファが短いとカクつき、パケットロス時にはワープ
症状 カクつき , ワープ , 不発・ロールバック
要因 遅延, パケットロス
誰に起きるか サーバー全体
いつ 常に
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:近い対象や戦闘中の対象は頻繁に、遠い対象はまれに送る、変わった部分だけを送って(デルタ圧縮)1回のサイズを減らし、送信頻度を上げる。クライアント:補間バッファの長さをパケット間隔に合わせて自動調整。
数値の目安 1秒に10回ならパケット間隔100ms、バッファ200ms。Ping 150msの片道遅延75msを足すと、相手を約0.3秒前の姿で見ることになります。
グラフでは 最初から常に高い · クライアントごとのパケット到着間隔、補間バッファの長さ
確認箇所 サーバー側のパケットキャプチャで1人のユーザーへ向かうフローだけに絞り、WiresharkのI/O Graphsで毎秒のパケット数と間隔を確認。ゲーム側のログがあれば、オブジェクトごとの更新間隔と、クライアントの補間バッファの余裕(次のスナップショットが届くまでの残り時間)も合わせて確認 該当する場合 位置の更新が毎秒5〜10回(間隔100〜200ms)と常にまばらで、補間バッファを200ms超に設定しているか、バッファの余裕が頻繁に0になる 該当しない場合 更新は細かく送られているのに到着間隔だけがぶれるなら、ジッター・パケットロス側。混雑時に遠いオブジェクトだけをまれにしか受け取らないなら、接続ごとの送信バジェット・優先度 確認手段 インフラのツールで確認(ゲームコード不要)
出典4件
一部のユーザーだけに起きる問題
原因24件 · メインページの章
回線が重い人がほかの人の画面でまとめて動く Laggy player seen by others (bursty inputs)
ID pt-slow-burst · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 外部・外部
回線が悪い人の入力は、不規則にまとまってサーバーに届きます。サーバーがティックごとに受け取った分だけ適用すると、ほかの人の目にはそのキャラクターが一瞬止まってから一気に何歩も進んで見えます。
なぜ 回線が重い人の移動コマンドが、あるティックには0個、あるティックには2〜3個ずつ届く → すると サーバーが受け取ったティックに一度に適用するため、そのキャラクターの位置が階段状に変わる → 画面では ほかの人の画面でそのキャラクターだけが一瞬止まっては一気にまとめて移動。ほかは問題なし
症状 早送り , ワープ
要因 ジッター, パケットロス
誰に起きるか 特定のキャラだけおかしく見える, 特定の地域・ISP
いつ 常に, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 外部・外部
ゲーム開発チームの対応 プレイヤーごとの入力バッファでコマンドを均等に分けて適用、入力のシーケンス番号を見て元の間隔どおりに適用、ほかの人の画面の補間バッファを増やすだけでは不十分(サーバーでの位置の記録自体が階段状になっているため)。
外部の対応 回線が重いユーザーに、有線接続、Wi-Fi・ルーターの点検を案内。
数値の目安 ジッターが80msなら、20ティック(50ms)のサーバーでティックあたりのコマンド数が0〜3個でばらつきます。
グラフでは 一部だけ高い · プレイヤーごとのティックあたり適用コマンド数、プレイヤーごとのジッター
確認箇所 サーバー側のパケットキャプチャで、報告されたユーザーが送ったパケットだけに絞り、ティック間隔(例:50ms)ごとに何個ずつ届いたかを数えてほかのユーザーと比較。サーバーログがあれば、プレイヤーごと・ティックごとに適用した移動コマンド数と入力のシーケンス番号を確認 該当する場合 報告されたユーザーのパケットだけがティックごとに0個と2〜3個を行き来してまとまって届き、そのユーザーのジッター・パケットロスが高く、ほかのユーザーのパケットは均等に届いている。そのユーザーが有線に切り替えると減る 該当しない場合 複数のキャラクターが一斉にまとめて動くなら、サーバーのティック遅延か見ている人側の回線。到着と適用が均等なのにそのキャラクターだけ飛んで見えるなら、見ている側の補間・表示の問題 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく サーバー権威型の構成では、これは正常な動作です。回線が重い1人のラグは、ほかの人には「その人がおかしな動きをする姿」としてだけ見え、ほかの人の操作やモンスターの動きには影響しません。ただし、その人と直接やり取りすること(取引、パーティでのギミック、PvPの判定)は一緒に遅れます。
出典3件
受信即時処理のサーバーで起きる早送り Event-driven processing of bursty inputs
ID pt-event-server · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
パケットが届くたびにすぐ処理して通知するサーバーでは、回線が重い人のまとまって届いた行動が立て続けに即実行されます。
なぜ 回線が重い人のスキル・移動のリクエストがまとまって届く → すると サーバーが受け取った瞬間に順番に実行し、すぐに全員へ通知 → 画面では ほかの人の目には、その人がスキルを一瞬で何個も使ったり、早送りのように動いたりする
症状 早送り
要因 ジッター
誰に起きるか 特定のキャラだけおかしく見える
いつ 特定の操作をしたとき, 常に
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:行動に付いた入力時刻の間隔どおりに実行(時刻は許容範囲内の場合だけ採用)、またはまとまって届いた行動を拒否せず、最小間隔(共通クールタイム)ずつ空けて順に実行、到着時刻だけを見てクールタイムをチェックしない(正常な入力が不発になる)。クライアント:行動に入力時刻を付けて送る。
グラフでは 一部だけ高い · プレイヤーごとの行動の実行間隔
確認箇所 サーバーログに、プレイヤーごとの行動の到着時刻、実行時刻、クライアントが付けた入力時刻(あれば)を記録し、実行間隔と入力間隔を比較。サーバー側のパケットキャプチャで、そのユーザーのパケットの到着間隔も合わせて確認 該当する場合 入力間隔は正常なのに、サーバーでの到着・実行間隔が数msに固まっており、固まった瞬間がほかの人たちからの早送りの報告時刻と重なる 該当しない場合 入力時刻の間隔から固まっているなら、クライアントかマクロ側。サーバーの実行間隔は均等なのにほかの人の画面でだけ固まって見えるなら、見ている人の回線 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
プレイヤーごとの入力バッファのサイズ Per-player server input buffer (jitter buffer)
ID pt-input-buffer · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが人ごとに入力を少しためておき、1ティックに1つずつ取り出して使うと、ほかの人の目にはなめらかですが、本人の行動がサーバーで確定するタイミングはその分遅れます。
なぜ サーバーが回線の重い人の入力をバッファにため、1ティックに1つずつ適用 → すると バッファが小さいと頻繁に空になり、そのキャラクターがその場に止まるか、サーバーが最後の入力から推測して動かす。大きいと本人の入力の確定が遅れる → 画面では 小さいとほかの人の目には一瞬止まって見え、大きいと本人のスキルの結果が遅れて出る(入力遅延)
症状 カクつき , 入力遅延
要因 ジッター
誰に起きるか 特定のキャラだけおかしく見える, 自分だけ
いつ 常に
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:人ごとに回線の状態に合わせてバッファサイズを自動調整、遅れたら2つずつ取り出して追いつく、バッファが頻繁に空になる人のクライアントには入力を早めに送るよう指示。クライアント:サーバーの指示に合わせて入力を少し早めに送る(クライアントの時間調整)。
数値の目安 ゲームによって違いますが、通常は1〜3ティック分です。VALORANTは128ティックのサーバーで、サーバー側のバッファを平均半フレーム(約4ms)と、さらに短く保っています。ジッターが大きい人だけバッファを増やす適応型が一般的です。
グラフでは 一部だけ高い · プレイヤーごとの入力バッファの長さ・空になった回数
確認箇所 サーバーに、プレイヤーごと・ティックごとに入力バッファに残っている入力数、バッファが空になって最後の入力から推測して埋めた回数、入力の到着から適用までにかかった時間を記録 該当する場合 バッファが小さい人は空になる回数が多く、その瞬間にほかの人の画面で短く止まる。バッファが大きい人は、入力から適用までの時間がバッファの長さの分だけ延びている 該当しない場合 バッファがほとんど空にならないのにほかの人の画面でカクつきが見えるなら、見ている側の補間の問題。バッファが短いのに入力遅延が大きいなら、RTTそのものか二重のティック待ち 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
特定の通信事業者のユーザーに集中する検証の誤検知 Anti-cheat / movement validation false positives on bad ISPs
ID pt-isp-validation · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
ジッターが大きい回線を使う人は入力がまとまって届くため、サーバーの速度・クールタイムのチェックに頻繁に引っかかります。
なぜ 特定の通信事業者・地域の回線のジッターが夜に大きくなる → すると まとまって届いた正常な入力を、サーバーが速度超過・クールタイム違反と判断 → 画面では その通信事業者のユーザーだけ引き戻し、スキル拒否、ひどいとサーバーから追い出されて切断
症状 引き戻し , 不発・ロールバック , 切断
要因 ジッター
誰に起きるか 特定の地域・ISP, 自分だけ
いつ 夜のピーク時間帯, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 チェックは数秒にわたる累積の許容量で行う、回線の状態(Ping・ジッター)を参考に基準を緩和、強制切断の前に警告段階を設ける、プレイヤーごとの入力バッファでまとまって届いた入力をティックごとに均等に分け、誤検知そのものを減らす。
インフラチームの対応 通信事業者ごとのパケットロス率・ジッターの分布を時間帯別に確認してゲーム開発チームに共有、その通信事業者の区間の経路を点検(双方向のmtr)、必要なら経路変更・通信事業者へのエスカレーション。
グラフでは 特定の時間帯だけ高い · 通信事業者(ASN)ごとの検証拒否・強制切断の数、通信事業者ごとのジッター
確認箇所 サーバーの検証拒否・補正・強制切断のログに接続元IPの通信事業者(ASN)と時刻を付け、通信事業者・時間帯ごとに集計。インフラチームは同じ時間帯にその通信事業者に向けて双方向のmtrを実行し、ジッター・パケットロスを確認 該当する場合 拒否・強制切断が特定の通信事業者に集中して夜に増え、同じ時間帯にその通信事業者のジッターも高く、数秒単位で合計した移動量はルールの範囲内 該当しない場合 通信事業者に関係なく特定のアカウントだけで繰り返すなら、実際のチートの可能性。すべての通信事業者で一緒に増えるなら、サーバーのティックが遅れてコマンドがまとめて適用されるサーバー側の原因(ティックバジェット超過) 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
ID pt-raid-member · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
全員が決まった瞬間に一緒に反応しなければならないレイドのギミックでは、回線が重い1人の遅れた反応がパーティ全体の失敗になります。
なぜ 「全員同時に散開」「1人がボタンを押す」のような全員で対処するギミック → すると 回線が重い人は予兆を見るのが遅れ、入力も遅れて届く → 画面では その1人のせいで全滅、ほかのパーティメンバーは「ラグい人のせい」と感じる
症状 不発・ロールバック , 入力遅延
要因 遅延
誰に起きるか 特定の場所・チャンネル, 特定のキャラだけおかしく見える
いつ 人が集中したとき, 特定の操作をしたとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:ギミックの判定の受付時間をPingの分だけ余裕を持たせる、予兆はサーバー時刻で前もって送る、1人の失敗が全滅につながらない設計。クライアント:受け取った予兆をサーバー時刻に合わせて再生。
グラフでは 一部だけ高い · ギミック失敗を招いたプレイヤーごとのRTT
確認箇所 サーバーのギミックログに、失敗を招いたプレイヤー、その人の入力の到着時刻、判定の受付時間、その人のRTT・パケットロスを記録 該当する場合 全滅を招いた入力のほとんどが同じ1人のもので、その人のRTTがパーティの平均よりはっきり高く、入力が受付時間の直後に届いている 該当しない場合 失敗がパーティメンバーに均等に分かれているなら、受付時間そのものが短い問題(Pingに削られる短い判定の受付時間)。回線が重い人の入力が受付時間内に届いているのに失敗するなら、サーバーの判定コード 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
モンスターの制御権が遅いクライアントにある Monster movement delegated to a player client
ID pt-mob-control · 主担当 ゲーム開発チーム・サーバー開発
サーバー負荷を減らすため、モンスターの移動計算を近くのプレイヤー1人のクライアントに任せるゲームがあります。その人の回線が悪いと、そのモンスターが全員の画面でおかしな動きをします。
なぜ サーバーがモンスターの移動計算を、最も近い(または先に来た)プレイヤーのクライアントに任せる → すると 任された人の結果報告が遅れたり、まとまったりしてサーバーに届く → 画面では そのモンスターだけが周囲全員の画面で一瞬止まってはワープ。任された本人の画面では問題なし
症状 ワープ , カクつき , 早送り
要因 ジッター, パケットロス
誰に起きるか 特定のキャラだけおかしく見える, 特定の場所・チャンネル
いつ 常に, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 制御権を回線の良い人に渡す(Ping・パケットロス基準)、報告が途切れたらサーバーが即座に回収、ボスのような重要なモンスターはサーバーが自ら計算。
グラフでは 一部だけ高い · モンスターごとの位置報告の間隔(制御権を持つクライアント別)
確認箇所 サーバーに、モンスターごとに制御権を持つクライアントと、そのクライアントの報告間隔・RTT・パケットロスを記録。サーバー側のパケットキャプチャで、そのクライアントが送ったパケットの到着間隔も確認できる 該当する場合 おかしく動くモンスターの制御権がすべて同じ1人にあり、その人の報告間隔がばらつくか途切れ、制御権をほかの人に渡すとすぐ正常になる 該当しない場合 サーバーが自ら計算するモンスターも同じように飛ぶなら、サーバーのティック遅延か見ている人側の回線。制御権を移しても飛び続けるなら、コマンド同期の経路計算の不一致 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく 任された人は問題ないと感じるため、報告は「モンスターがおかしい」という形でしか来ません。1人を除く全員が同じモンスターをおかしく見ているなら、まずそのモンスターの制御権を誰が持っているかを確認します。
出典2件
特定キャラクターのデータ肥大化 One character with oversized data (inventory, mail, buffs)
ID pt-heavy-char · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
アイテム・郵便が数千個たまっていたり、フレンド・ブロックリストやバフが極端に多かったりするキャラクターは、接続時・保存時・周囲への通知で扱う量がほかの人の数倍になります。回線に関係なく、そのキャラクターでだけ重くなります。
なぜ 長く育てたキャラクターやイベント報酬で、インベントリ・郵便受けに数千個たまる → すると 接続・エリア移動・保存のたびにその分DBを読み書きし、周囲に送る装備・バフの情報も大きい → 画面では そのキャラクターだけ入場時のロードが長く、インベントリ・郵便を開くときに一瞬止まる。保存をゲームスレッドで待つサーバーなら、周囲の人まで一時的に止まる
症状 接続不可・無限ロード , 入力遅延 , フリーズ
要因 ストール
誰に起きるか 自分だけ, 特定の機能だけ
いつ 接続直後・メンテ明け, 特定の操作をしたとき, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応 インベントリ・郵便の保管上限と古い郵便の自動整理、必要な部分だけを分けて読み込む、保存は変わった部分だけをゲームスレッドの外で。
インフラチームの対応 スロークエリログから同じキャラクターで繰り返される遅いクエリを見つけてゲーム開発チームに伝える、アイテム・郵便の行数が多いキャラクターの上位リストを提供。
数値の目安 アイテム1個がDBの1行なら、アイテム5,000個のキャラクターは接続のたびに5,000行を読みます。ふつうのキャラクターの数十倍です。
グラフでは 一部だけ高い · キャラクターごとの接続・保存時間、キャラクターごとのDB読み取り行数
確認箇所 DBのスロークエリログ(MySQL slow query log、PostgreSQL log_min_duration_statement)で同じキャラクターIDで繰り返される遅い読み取り・保存を探し、アイテム・郵便テーブルのキャラクターごとの行数の上位リストを抽出 該当する場合 スロークエリが一部のキャラクターIDに集中し、そのキャラクターのアイテム・郵便の行数が平均の数十倍で、別のPC・回線から接続しても同じように遅い 該当しない場合 同じアカウントの別キャラクターやほかのユーザーも一緒に遅いなら、DBサーバー・ロック側。そのキャラクターが別のPCでは問題ないなら、ユーザーの環境 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく 同じキャラクターで別のPC・回線から接続しても同じように重く、同じアカウントの別キャラクターは問題ないなら、キャラクターデータを疑います。報告にキャラクター名が欠かせない理由です。
出典3件
ID pt-phase · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
2つのキャラクターが別のチャンネルやインスタンスにいたり、クエストの進行度によって見えるNPCが変わる別の「フェーズ」にいたりすると、互いに違う世界を見ることになります。
なぜ 2つ目のキャラクターが別のチャンネルに割り当てられるか、クエストの段階が違う → すると サーバーがそのキャラクターにはそのNPCを送らない(正常) → 画面では 片方にだけNPCがいない。バグのように見えるが設計どおり
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ 常に, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:チャンネル・フェーズの情報をクライアントに送る、QAチェックリストに「2つのキャラクターのチャンネル・クエスト段階を確認」を追加。クライアント:チャンネル・フェーズを画面に表示。
グラフでは 一部だけ高い · クライアントごとの周囲のオブジェクト数、チャンネル・フェーズ
確認箇所 2つのキャラクターのチャンネル番号とそのクエストの進行段階をゲーム画面で比較し、同じチャンネル・段階にそろえて再確認。サーバーのオブジェクト送信ログがあれば、そのNPCをそのキャラクターに送らなかった理由(チャンネル・フェーズ)を確認 該当する場合 2つのキャラクターのチャンネルかクエスト段階が違い、同じにそろえるとNPCが見える 該当しない場合 チャンネル・段階が同じなのに片方にだけいないなら、ロード中に届いた出現通知の破棄、入場直後に集中する出現情報の欠落、視界登録の順序の乱れ側 確認手段 ユーザー側の環境で確認
もっと詳しく クエストの進行をアカウント単位で保存しているか、キャラクター単位で保存しているかも確認します。同じアカウントの2つのキャラクターなら、片方の進行がもう片方のフェーズを変えることがあります。
出典2件
ロード中に届いた出現通知の破棄 Spawn messages dropped before the client is ready
ID pt-loading-drop · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゾーンに入るとすぐにサーバーが周囲のNPCの出現通知を送りますが、クライアントがまだマップを読み込んでいる最中なので、その通知を破棄してしまいます。
なぜ サーバーが入場処理の直後に周囲のオブジェクトの出現通知を送信 → すると クライアントはロード中でメッセージハンドラーがまだないため、通知を破棄 → 画面では サーバーは送信済みとして扱い、再送しない。視界から外れて戻ってくるまでNPCが表示されない
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ 接続直後・メンテ明け, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:ロードが終わったら「準備完了」を送る、またはロード中に受け取ったパケットを保管しておいて処理。サーバー:「準備完了」を受け取ってから周囲の情報を送信。
数値の目安 同じPCで2つのクライアントが同時にロードしたり、ロードする側がバックグラウンドウィンドウだったりすると、CPU・ディスクを分け合ううえに処理も制限されるため、そちらのロードが数倍長くなることがあります。サーバーの入場処理が速くなっても、同じバグが表に出ます。
グラフでは 一部だけ高い · クライアントごとのロード時間、ロード中に破棄したメッセージ数
確認箇所 クライアントがロード中に受け取って破棄したメッセージの数・種類とロード完了時刻を、サーバーが出現通知を送った時刻と比較。同じPCで2つのクライアントを同時にロードするか、ロードする側をバックグラウンドウィンドウにすると再現しやすい 該当する場合 表示されないNPCの出現通知をサーバーは送っており、到着時刻がロード完了前で、その時間に破棄したメッセージ数が増えている。ロードが長い側のクライアントでだけ起きる 該当しない場合 出現通知がロード完了後に届いているのに表示されないなら、基準スナップショットの欠落かオブジェクトIDの再利用による混同。サーバーがそのNPCの通知をそもそも送っていないなら、視界登録の順序の乱れか、チャンネル・フェーズの違い 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
視界登録の順序の乱れ Interest-management race on enter/leave
ID pt-aoi-race · 主担当 ゲーム開発チーム・サーバー開発
キャラクターが視界グリッドに登録される瞬間と、NPCがグリッドのセルを移る瞬間が重なると、そのNPCの出現通知が漏れることがあります。
なぜ 入場・チャンネル移動・テレポートの処理とNPCの移動が同じ瞬間に重なる → すると 「新たに見えるようになったオブジェクト」の計算からそのNPCが漏れる → 画面では 特定のNPC数体だけが表示されないか、すでに去ったNPCが残っている
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ 移動中・マップ切り替え時, ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 視界の更新を1つのスレッド・1つの順序で処理、定期的に「見えているリスト」全体を合わせ直す。
グラフでは 不定期なスパイク · サーバーの見えているリストとクライアントのオブジェクトリストの差分数
確認箇所 サーバーに、視界グリッドへの登録、オブジェクトのセル移動、出現・消滅通知の送信をティック番号とともに記録し、定期的にサーバーの「見えているリスト」とクライアントが持つリストを比較 該当する場合 漏れたNPCが、そのキャラクターの入場・テレポート処理と同じティックにセルを移っており、そのNPCへの出現通知の送信記録がない 該当しない場合 出現通知は送ったのにクライアントが受け取れなかったか破棄したなら、伝達側(入場直後に集中する出現情報の欠落、ロード中に届いた出現通知の破棄)。いつも同じNPCだけが漏れるなら、フェーズか表示オプションの違い 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
基準スナップショットの欠落 Lost baseline for delta compression
ID pt-baseline · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが「前回から変わったものだけ」を送る方式では、最初に1回送る全体の情報(基準)を失うと、その後の差分を適用できません。
なぜ オブジェクトの全体情報(基準)のパケットが失われるか、処理前に破棄される → すると クライアントはその後の差分を適用する対象がないため無視 → 画面では そのオブジェクトが表示されないか、かなり後で突然現れる
症状 表示されない・ゴースト , ワープ
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:基準は受信確認(ACK)を受け取るまで必ず再送、差分はクライアントが受信を確認した基準に対してだけ作る。クライアント:基準は実際に適用してから受信確認(ACK)を送る、知らないオブジェクトの差分を受け取ったらサーバーに再要求。
グラフでは 不定期なスパイク · 知らないオブジェクトの差分の受信数
確認箇所 クライアントが基準なしに受け取った差分を破棄した回数とオブジェクトIDを、サーバーがそのオブジェクトの基準を送った時刻・ACKを受け取った時刻と照合。開発環境でパケットロスを加えて(tc netemのloss、Unrealのネットワークエミュレーションのパケットロス率)再現 該当する場合 表示されないオブジェクトについて、サーバーは基準を送ったもののACKを受け取れていないのに差分だけを送り続け、クライアントはその差分を破棄している 該当しない場合 基準がACKまで受け取られてクライアントに適用されているのに表示されないなら、消滅通知の欠落かオブジェクトIDの再利用による混同 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典4件
消滅通知の欠落(ゴースト) Missed despawn (ghost entity)
ID pt-ghost · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
逆に「消えた」という通知を取りこぼすと、すでに死んだか去ったNPC・プレイヤーが自分の画面にだけ残ります。
なぜ 死亡・退出・視界外への移動の通知が失われるか、順序が入れ替わる → すると クライアントはそのオブジェクトがまだいると判断 → 画面では 叩いても反応しないモンスター、すでに抜けたプレイヤーが立っている
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ ときどきランダムに, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:定期的に「今見えているリスト」を送る。クライアント:リストにないオブジェクトは削除、動くはずのオブジェクトの更新が長い間なければ非表示にする。
グラフでは 不定期なスパイク · クライアントにだけ残ったオブジェクト数
確認箇所 サーバーが送る「今見えているリスト」とクライアントが持つオブジェクトリストを比較してクライアントにだけあるオブジェクトを数え、消滅通知の送信・受信ログをオブジェクトIDで照合 該当する場合 ゴーストの消滅通知をサーバーは送ったのにクライアントに受信記録がないか、消滅が出現より先に届いて順序が逆転している 該当しない場合 サーバーの見えているリストにもそのオブジェクトが残っているなら、サーバー側のオブジェクト整理漏れ。同じIDで新しいオブジェクトが現れた直後なら、オブジェクトIDの再利用による混同 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
入場直後に集中する出現情報の欠落 Initial spawn burst lost (unreliable channel, receive buffer, fragmentation)
ID pt-spawn-burst · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゾーンに入った瞬間、サーバーは周囲の数十〜数百個のオブジェクトの出現情報を一気に送ります。これを非信頼(unreliable)チャネルで送ったり、ロード中でソケットを読めない間に受信バッファがあふれたりすると、一部が消えて二度と届きません。
なぜ 入場直後に出現情報が短時間に集中して届く → すると ロード中のクライアントがソケットを読むのが遅れてOSの受信バッファがあふれるか、大きなUDPパケットがフラグメント化され、フラグメントを1つ失っただけで丸ごと消える。非信頼チャネルなら再送もされない → 画面では ロードが遅い側のクライアントでだけNPCが数体抜ける。視界から外れて戻ると見える
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ 接続直後・メンテ明け, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:出現・消滅通知は必ず再送が保証される信頼チャネルで送る、初期情報は分割して送る。クライアント:受信はロードとは別のスレッドで行う、受信バッファのサイズを増やす。
数値の目安 PCのUDP受信バッファのデフォルト値はOSによって違いますが、たいてい数十〜数百KBです。人の多い町の入場情報がこれより大きいと、ロードのせいでソケットを少し読めないだけであふれます。
グラフでは 接続直後・メンテ明けに急増 · 入場直後の受信量、出現通知の欠落数
確認箇所 サーバーが入場直後に送った出現通知の数とクライアントが受け取った数を比較し、どのチャネル(信頼・非信頼)で送ったかを確認。サーバー側のパケットキャプチャで、入場直後にそのユーザーに送った量とフラグメント化されたパケット(Wiresharkのフィルター:ip.flags.mf == 1 || ip.frag_offset > 0)を確認 該当する場合 受け取った数が送った数より少なく、抜けたものが入場直後の集中区間に固まっており、非信頼チャネルで送ったか、大きなパケットがフラグメント化されている。ロードが遅い側のクライアントでより頻繁に起きる 該当しない場合 送った数と受け取った数が同じなのに表示されないなら、受け取った後に破棄した(ロード中に届いた出現通知の破棄)か、視界計算の問題。入場直後に関係なく随時抜けるなら、回線のパケットロス 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典4件
オブジェクトIDの再利用による混同 Entity ID reused without a generation counter
ID pt-id-reuse · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
倒されたNPCが再び出現するときにサーバーが同じオブジェクトIDを使い回すと、その間に消滅通知を取りこぼしたクライアントは、新しいNPCを古いNPCと誤認します。
なぜ NPCが倒され、同じオブジェクトIDで再出現 → すると 消滅通知を取りこぼしたクライアントは「すでに知っているオブジェクト」として出現通知を無視するか、死亡状態のまま残す → 画面では 片方の画面にだけNPCがいないか倒れたまま見える、別のNPCの姿で見えることもある
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ ときどきランダムに, 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:オブジェクトIDに世代番号を付けて再利用を区別。クライアント:すでに知っているIDの出現通知を受け取ったら、既存のオブジェクトを削除して新たに作る。
グラフでは 不定期なスパイク · すでに知っているIDの出現通知の数
確認箇所 サーバーに、オブジェクトIDごとの生成・削除時刻(世代番号があれば一緒に)を記録し、クライアントがすでに知っているIDで出現通知を受け取った回数と、視界更新時に「変化なし」として処理された削除・再生成を数える 該当する場合 表示されないか倒れたまま見えるNPCのIDが直前に倒されたNPCと同じで、その間にそのクライアントが消滅通知を受け取れていないか、サーバーが消滅・出現の通知をどちらも送っていない 該当しない場合 IDに世代番号があり、比較にも使っているなら、この原因ではない。再利用されたIDでないのに表示されないなら、出現通知の欠落側 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく サーバー側でも起きます。視界内のオブジェクトリストをIDだけで比較すると、2回の視界更新の間に倒されて同じIDで再スポーンしたNPCを「変化なし」とみなし、消滅・出現の通知をどちらも送りません。視界更新のタイミングが人ごとにずれていると、その瞬間に当たったクライアントだけがこの問題に遭います。
出典2件
固定UDPポートの衝突 Two clients bound to the same local UDP port
ID pt-port-collision · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
クライアントが決まったローカルポートを使うように作られていると、同じPCの2つ目のクライアントはそのポートを使えないか、1つ目とパケットを分け合って受け取ることになります。
なぜ 2つのクライアントが同じローカルUDPポートを開こうとする(再利用オプションで無理に共有) → すると OSが届いたパケットを片方のソケットにだけ渡すか、どちらが受け取るかを保証しない。ルーターとサーバーも2つのクライアントを同じアドレスとみなす → 画面では 片方はワールドのパケットを受け取れず、NPC・ほかのプレイヤーが表示されないか切断される
症状 表示されない・ゴースト , 切断 , 接続不可・無限ロード
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ
いつ 接続直後・メンテ明け, 常に
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:ローカルポートはOSに自動で選ばせる(0番をバインド)。サーバー:接続ごとに発行したセッショントークンで接続を区別。
グラフでは 一部だけ高い · クライアントごとの受信パケット数
確認箇所 ユーザーのPCで2つのクライアントを起動したまま、コマンドプロンプトでnetstat -ano -p udpを実行し、ゲームプロセス(PID)ごとに開いているローカルUDPポートを確認。サーバー側では、2つのセッションが同じグローバルIP・同じポートから来ているかを確認 該当する場合 2つのゲームプロセスが同じローカルポートにバインドされているか、サーバーから2つのセッションが同じIP・ポートに見える。片方だけ起動すれば正常 該当しない場合 2つのクライアントが別々のローカルポートを使っているのに片方がおかしいなら、IP・端末基準のセッション識別バグか、多重起動の制限 確認手段 ユーザー側の環境で確認
出典3件
ID pt-session-key · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーや中継サーバーが接続をIPや端末IDで区別していると、同じPC(同じグローバルIP)の2つのクライアントを1人として認識します。
なぜ セッションテーブルをIP、またはIP+端末IDで作っている → すると 2つ目のクライアントの情報が1つ目のセッションに上書きされるか混ざる → 画面では 片方はNPCが表示されず、もう片方は切断されるかほかの人の情報を受け取る
症状 表示されない・ゴースト , 切断
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ, 同じ家, 特定の地域・ISP
いつ 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:サーバー・中継サーバーとも接続ごとに一意のセッショントークンで区別、同じ家(ルーターのNATの内側)の複数人や、通信事業者が1つのIPを複数の契約者に割り当てるモバイル回線(CGNAT)のユーザーも同じ問題に遭うので必ず修正。クライアント:起動したクライアントごとに個別に受け取ったセッショントークンを使う。
グラフでは 一部だけ高い · 同じグローバルIPの同時セッション数、セッション上書きの数
確認箇所 サーバー・中継サーバーのログに、セッション検索に使ったキー、セッショントークン、クライアントのIP・ポートを記録し、同じIPから2つ目の接続が来た瞬間に既存のセッションが変わったかを確認。同じPCで2つのクライアントを順に起動すると再現する 該当する場合 2つ目のクライアントが接続した瞬間に1つ目のセッションのアドレスやキャラクター情報が変わり、同じルーターやモバイル回線(CGNAT)の内側にいるほかのユーザーでも同じ切断が見られる 該当しない場合 同じIPの2つのセッションが別々のトークンで個別に維持されているなら、この原因ではない。2つのプロセスが同じローカルポートを使っているなら、固定UDPポートの衝突 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典1件
多重起動の制限 Multi-client restriction policy
ID pt-multiclient · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
セキュリティモジュールやサーバーのポリシーが1台のPCでの複数クライアントを制限していると、2つ目のクライアントは起動・接続ができないか、先に起動した側が切断されます。一部のゲームは追加のクライアントの機能だけを制限します。
なぜ セキュリティモジュールが多重起動を検知、またはサーバーが同じ端末からの追加接続を制限 → すると 2つ目の起動・接続を拒否するか、片方を切断。まれに追加のクライアントの一部の機能だけを遮断 → 画面では 接続不可か片方の切断。機能だけを制限するゲームでは、片方だけNPC・ショップが表示されない
症状 接続不可・無限ロード , 表示されない・ゴースト , 切断
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ
いつ 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:制限するなら明確な案内メッセージを出す、セキュリティモジュールにQA用の例外を設定。サーバー:同じ端末からの接続制限にもQA用の例外を設定。
グラフでは 一部だけ高い · 理由別の接続拒否・切断数(多重接続)
確認箇所 2つ目のクライアントを起動したときに出るメッセージと、先に起動した側の切断メッセージを確認。サーバーの接続拒否・強制切断のログに、多重接続・同一端末などの理由コードが残っているかを確認 該当する場合 2つ目の起動・接続の瞬間に拒否メッセージが出るか、先に起動した側が多重接続を理由に切断され、クライアントを1つだけ起動すれば問題ない 該当しない場合 拒否・切断の理由なしに両方とも接続できているのに片方だけNPCが表示されないなら、固定UDPポートの衝突、IP・端末基準のセッション識別バグ、ロード・表示側の原因 確認手段 ユーザー側の環境で確認
出典1件
ID pt-background · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
バックグラウンドウィンドウのクライアントでは、ゲーム・エンジン・OSがフレームと処理を減らします。受け取ったパケットを時間内に処理できず、詰まったりあふれたりします。
なぜ ゲームのオプションやグラフィックスドライバーのバックグラウンドのフレーム制限(例:NVIDIAドライバーでは毎秒20〜200の間で指定)、省電力、エンジンのバックグラウンド停止設定。OSも前面のウィンドウ(フォアグラウンド)にCPU・GPUを優先的に割り当てる → すると フレームごとに処理するパケット数が減ってキューがたまり、受信バッファがあふれると破棄される → 画面では ウィンドウを前面に出すとまとめて現れるか、一部のNPCが最後まで表示されない
症状 表示されない・ゴースト , 早送り , 切断
要因 ストール, パケットロス
誰に起きるか 同じPCの片方のクライアントだけ
いつ しばらく放置した後, 常に
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
ゲーム開発チームの対応 ネットワーク受信はゲームループとは別のスレッドで継続、バックグラウンドでも最低限の処理量を保証、エンジンのバックグラウンド実行設定(UnityではrunInBackground)を有効にする。
外部の対応 ユーザーに、グラフィックスドライバーのバックグラウンドのフレーム制限とPCの省電力モードを切るよう案内。
数値の目安 Unityは、runInBackgroundの設定が無効だと、ウィンドウがフォーカスを失った瞬間にゲームループが止まります。受信をそのループの中だけで行っていると、その間パケットがまったく処理されません。
グラフでは 途切れた後にまとめて到着 · クライアントのフレーム間隔、フレームあたりの処理パケット数
確認箇所 同じPCで片方のウィンドウを前面、もう片方を背面に置き、役割を入れ替えながら比較。PresentMonで2つのプロセスのフレーム間隔を測り、ゲーム側のログがあれば、ウィンドウのフォーカス状態とフレームごとに処理したパケット数を確認 該当する場合 バックグラウンドウィンドウのときだけフレーム間隔が大きく延びるか(ドライバーの制限なら、設定したフレームレートに対応する間隔で頭打ちになる)処理が止まり、ウィンドウを切り替えると問題もほかのクライアントへ移る 該当しない場合 前面のウィンドウでも同じように起きるなら、バックグラウンドの制限のせいではない。ウィンドウの位置に関係なくいつも同じクライアントだけがおかしいなら、表示オプションかバージョンの違い 確認手段 ユーザー側の環境で確認
出典4件
ID pt-asset-lock · 主担当 ゲーム開発チーム・クライアント開発
2つのクライアントが同じキャッシュフォルダーに同時に書き込んだりファイルをロックしたりすると、片方がNPCのモデル・テクスチャを読み込めなくなります。
なぜ 2つのクライアントが同じインストールフォルダーのキャッシュ・アップデートファイルに同時に書き込む → すると ファイルロックの失敗や、書きかけのファイルを読んでロードに失敗 → 画面では ネームプレートはあるのにキャラクターモデルがない、または透明なNPC
症状 表示されない・ゴースト
要因 ストール
誰に起きるか 同じPCの片方のクライアントだけ
いつ 接続直後・メンテ明け, 移動中・マップ切り替え時
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 クライアントごとのキャッシュフォルダー、ファイルロック失敗時の再試行、ロード失敗時はデフォルトのモデルだけでも表示。
グラフでは 一部だけ高い · クライアントごとのアセットのロード失敗数
確認箇所 ユーザーのPCでProcess Monitorを使ってゲームのインストール・キャッシュフォルダーのパスだけに絞り、2つのゲームプロセスのファイルのオープン・書き込みの結果を確認。クライアントログがあれば、アセットのロード失敗とファイルオープンのエラーコード(ERROR_SHARING_VIOLATION)を探す 該当する場合 表示されないモデルのファイルオープンが共有違反・ロック失敗で終わっており、同じ時刻にほかのクライアントがそのファイルに書き込んでいた。1つだけ起動するか、インストール・キャッシュフォルダーを分けると消える 該当しない場合 クライアントを1つだけ起動しても同じモデルが表示されないなら、ファイルの破損かクライアントのバージョン・データの不一致。ファイルは正常に開けたのに描画されないなら、メモリ・VRAM不足 確認手段 ユーザー側の環境で確認
出典2件
ID pt-vram · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
2つのクライアントがビデオメモリを分け合うと、新たに必要なモデル・テクスチャを載せる場所がなく、一部が描画されません。
なぜ 2つのクライアントがVRAM・RAMを分け合う。OSはバックグラウンドウィンドウのビデオメモリの割り当てを先に減らすこともある → すると エンジンが新しいモデル・テクスチャを載せられないか、下ろしては載せ直すことを繰り返す → 画面では NPCが遅れて現れる、ぼやける、表示されない、カクつき
症状 表示されない・ゴースト , カクつき
要因 ストール
誰に起きるか 同じPCの片方のクライアントだけ
いつ 移動中・マップ切り替え時, 人が集中したとき
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
ゲーム開発チームの対応 メモリバジェットに合わせた品質の自動調整、ロード失敗時は代替モデルを表示。
外部の対応 2つのクライアントを同時に起動するユーザーに、グラフィック品質を下げるか低スペックモードを使うよう案内、推奨VRAM・RAMの仕様を案内。
グラフでは 上限で頭打ち · プロセスごとの専用GPUメモリ使用量
確認箇所 ユーザーのPCのタスクマネージャーの「詳細」タブに「専用GPUメモリ」列を追加し、2つのクライアントの使用量の合計をグラフィックスカードのVRAM容量と比較。ゲーム側では、DXGIのQueryVideoMemoryInfoが返すバジェット(Budget)と現在の使用量(CurrentUsage)を記録 該当する場合 2つのクライアントの使用量の合計がVRAM容量の付近で頭打ちになり、現在の使用量がバジェットを超えた時刻にモデル・テクスチャのロード失敗が集中。品質を下げるか1つだけ起動すると消える 該当しない場合 VRAMに余裕があるのに表示されないなら、キャッシュ・アセットファイルへの同時アクセスの競合か、表示オプションの違い 確認手段 ユーザー側の環境で確認
出典3件
表示オプションの違い Different display settings
ID pt-display-option · 主担当 ゲーム開発チーム・クライアント開発
表示人数の制限、NPCのネームプレート・モデルの非表示、低スペックモードなどのオプションが2つのクライアントで違うと、見えるものが変わります。
なぜ 片方のクライアントだけ「周囲のキャラクター表示数の制限」や低スペックモード → すると 遠くにいるか優先度の低いNPCを描画しない(正常) → 画面では 片方にだけNPCがいない
症状 表示されない・ゴースト
要因 ストール
誰に起きるか 同じPCの片方のクライアントだけ, 自分だけ
いつ 人が集中したとき, 常に
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 オプションで非表示にしたオブジェクトだとわかるように表示、設定ファイルをクライアントごとに分けて混ざらないようにする。
グラフでは 一部だけ高い · クライアントごとの画面に描画したオブジェクト数
確認箇所 2つのクライアントの表示人数の制限、ネームプレート・モデルの非表示、低スペックモードの設定を並べて比較し、片方をもう片方とまったく同じにそろえてみる。2つのクライアントが1つの設定ファイルを共有して互いに上書きしていないかも確認 該当する場合 設定を同じにそろえると2つの画面が同じになり、表示されなかったNPCは表示制限人数の外にある遠いオブジェクトか、優先度の低いオブジェクトだった 該当しない場合 設定をまったく同じにそろえても片方にだけいないなら、チャンネル・フェーズの違いか出現通知の欠落側 確認手段 ユーザー側の環境で確認
出典1件
ID pt-version · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
2つ目のクライアントが別のインストール版だったりアップデートが済んでいなかったりすると、サーバーが送った新しいNPCのIDを知らないため、黙って無視します。
なぜ 別フォルダーのインストール版、またはアップデート中に起動したクライアント → すると 知らないNPC ID・モデルIDを受け取ると読み飛ばす → 画面では 新しく追加されたNPCだけが片方で表示されない
症状 表示されない・ゴースト
要因 パケットロス
誰に起きるか 同じPCの片方のクライアントだけ
いつ 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 クライアント:接続時にデータのバージョンを送る、知らないIDを受け取ったらログを残して代替表示。サーバー:接続時にデータのバージョンを確認し、違えば接続拒否・アップデートの案内。
グラフでは 一部だけ高い · クライアントのバージョンごとの、知らないIDの受信数
確認箇所 2つのクライアントの実行ファイルのパスと、画面・ログに出るクライアント・データのバージョンを比較。ゲーム側では、接続時に送ったデータのバージョンと、知らないNPC・モデルIDを受け取って読み飛ばした回数を記録 該当する場合 2つのクライアントのバージョンかインストールフォルダーが違い、表示されないNPCが最近のアップデートで追加されたもので、アップデートを終えたインストール版では表示される 該当しない場合 バージョンとインストールフォルダーが同じなのに片方にだけいないなら、チャンネル・フェーズの違いか、ロード・伝達側の原因 確認手段 ユーザー側の環境で確認
出典1件
接続ごとの送信バジェット・優先度 Per-connection bandwidth budget and priority
ID pt-priority · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが接続ごとに送る量に上限を設けて近いものから送ると、上限が低く設定された側は、遠くにいるNPCを遅れて受け取るか、受け取れません。
なぜ 人の多い場所で、サーバーが接続ごとの送信量の上限内で重要度順に送信 → すると 帯域幅の推定が低く出た接続(例:バックグラウンドウィンドウで受信確認が遅れている側)は、後ろのほうのオブジェクトを後回しにし続ける → 画面では 遠くにいるNPCが片方でだけ遅れて見えるか、表示されない
症状 表示されない・ゴースト , 入力遅延
要因 遅延
誰に起きるか 同じPCの片方のクライアントだけ, 特定の場所・チャンネル
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:後回しになったオブジェクトの優先度を時間とともに上げる(スタベーション防止)、最低限の更新周期を保証。クライアント:バックグラウンドでも受信確認を遅れずに送り、帯域幅の推定が下がらないようにする。
グラフでは 人数・負荷に連動して上昇 · 接続ごとの後回しにしたオブジェクト数、接続ごとの送信量
確認箇所 サーバーに、接続ごとのティック別送信バイト数、送信上限(推定帯域幅)、送れずに後回しにしたオブジェクト数、オブジェクトごとの最後の送信からの経過時間を記録。UnrealではNetworking Insightsで接続ごとのパケットサイズと、その中に含まれるレプリケーション対象を確認できる 該当する場合 表示されないNPCがその接続で長く後回しにされたオブジェクトで、その接続の上限がほかの接続より低く、混雑するほど後回しのオブジェクトが増える 該当しない場合 後回しのオブジェクトがなく、そのNPCも時間どおりに送っているなら、送信後の段階(受信バッファ、ロード、表示オプション)。すべての接続が上限に張り付いているなら、サーバー全体の送信量・視界設計の問題 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典3件
時刻推定の誤差によるオブジェクトの保留 Clock estimate error holds or discards entities
ID pt-clock-hold · 主担当 ゲーム開発チーム・クライアント開発
クライアントが推定したサーバー時刻がずれていると、届いたばかりのオブジェクト情報を「まだ未来」として保留したり、「古すぎる」として破棄したりします。
なぜ 片方のクライアントのサーバー時刻の推定が大きくずれる(ロード中の測定、省電力からの復帰) → すると 補間の基準時刻とオブジェクト情報の時刻が合わない → 画面では オブジェクトが遅れて現れるか、止まったまま見える
症状 表示されない・ゴースト , カクつき
要因 遅延
誰に起きるか 同じPCの片方のクライアントだけ
いつ しばらく放置した後, 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 時刻同期を定期的にやり直し、差が大きければ即座にリセット、ロード中や省電力からの復帰直後に測った値は使わない。
グラフでは 一部だけ高い · クライアントごとのサーバー時刻の推定誤差
確認箇所 クライアントに、推定したサーバー時刻、RTT、時刻同期をやり直した時刻、オブジェクト情報を保留・破棄した回数を記録。ロード直後や省電力からの復帰直後に再現してみる 該当する場合 問題が起きたクライアントだけ推定誤差がリセット基準(UnityではhardResetThresholdSec、デフォルト0.2秒)を超え、オブジェクト情報を未来として保留したり過去として破棄したりした記録があり、時刻同期をやり直すとすぐ正常になる 該当しない場合 推定誤差が小さいのに遅れて現れるなら、接続ごとの送信バジェット・優先度か、ロード側の原因 確認手段 ゲームサーバー・クライアントのログ・メトリクスが必要
出典2件
TCP再送の根本原因
原因20件 · メインページの章
無線区間のパケットロス Wi-Fi / cellular link loss
ID rt-wireless · 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
Wi-Fiとモバイル回線は、無線区間で何度か再送し、それでも届かなければパケットを破棄します。破棄されたパケットは、TCPがかなり後になってから送り直します。
なぜ 電波が弱いか干渉が強く、無線区間での送信が連続して失敗 → すると 無線機器の再試行上限(通常は数回〜十数回)を超えるとパケットを破棄 → 画面では TCPの再送を待つ間止まり、後続のパケットは受信バッファで待たされた後に早送り
症状 フリーズ , 早送り , ワープ
要因 パケットロス, ジッター
誰に起きるか 自分だけ, 同じ家
いつ ときどきランダムに, 移動中・マップ切り替え時
担当 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:TCP_NODELAYを有効にする(Nagleアルゴリズムが有効だと、RACKがロス判定に使う後続パケットがない)、再送で詰まっている間に送る状態更新はためずに最新のものだけ送る(カーネルにたまる量はTCP_NOTSENT_LOWATで制限)。クライアント:TCP_NODELAYを有効にする(自分の入力方向のパケットロスはクライアントOSが回復)、パケットロスが集中したりPingが急上昇したりしたら画面にネットワーク状態を表示。
インフラチームの対応 RACK-TLPでロス回復を速くする(サーバーは無線区間のパケットロスを防げず、できるのは回復を速くすることまで)、最新Linuxのデフォルト値であるnet.ipv4.tcp_recovery=1(RACK)・net.ipv4.tcp_early_retrans=3(TLP)が変更されていないか確認。
外部の対応 ユーザーに、有線接続、5GHz・6GHzの利用、ルーターの設置場所・チャンネルの変更を案内。
数値の目安 無線区間のパケットロスが1%なら、ゲームのパケット100個のうち1個が消えます。1秒に10個受信するなら、10秒に1回ほどの割合でカクッと止まります。RACK-TLPがなければ、そのたびにRTO(Ping + 200ms以上)の間止まります。
グラフでは 一部だけ高い · 接続ごとの再送率、接続ごとのRTT(Ping)
確認箇所 ユーザーのPCからルーター(ゲートウェイ)のアドレスとゲームサーバーにそれぞれpingを数百回送ってパケットロスと遅延の幅を比較し、有線やモバイルデータに切り替えて再測定。サーバーではss -tiでそのユーザーの接続のretransとrtt(平均/偏差)を確認 該当する場合 ルーターまでのpingですでにパケットロスやばらつく遅延が見られ、有線に切り替えると消える。サーバーから見ると、そのユーザーの接続だけretransとRTTの偏差が大きい 該当しない場合 ルーターまでは問題がなく、その先からパケットロスが始まるなら通信事業者・経路側(「ボトルネックでのキューあふれ」「経路変更・ECMPの不良経路」)。同じ通信事業者の複数のユーザーが同時に悪化するなら、通信事業者の区間から確認 確認手段 ユーザー側の環境で確認
もっと詳しく 無線機器の再試行はジッターを生み(再試行ごとに数ms)、再試行上限を超えた場合だけがパケットロスになります。そのため無線の品質が悪くなるほど、「ジッター → ときどき止まる → 頻繁に止まる」の順に症状が大きくなります。アクセスポイント(AP)の間を移る瞬間(ローミング)には、数十ms〜数秒の間、続けてパケットを失うこともあります。モバイル回線は基地局との区間で多く再送するため、パケットロスよりも数百msの遅延の急上昇として現れることが多くなります。
実際の事例 Square Enix 2021: FINAL FANTASY XIVの拡張パッケージ発売時の混雑とログイン待機列のエラー
出典8件
ID rt-queue-drop · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部, ゲーム開発チーム・クライアント開発
ルーター、通信事業者どうしの接続区間、データセンターの回線のように、最も細い箇所のキューが満杯になると、新しく届くパケットを破棄します。
なぜ 動画・ダウンロード・他のユーザーのトラフィックでボトルネック区間が満杯 → すると キューが満杯の間、新しく到着するパケットが続けて破棄される(tail drop)。破棄されなかったパケットも満杯のキューの末尾で待たされる → 画面では 複数のパケットが一度に消え、長く止まった後に早送り、夜の時間帯に多い
症状 フリーズ , 早送り , 引き戻し
要因 パケットロス, 遅延
誰に起きるか 同じ家, 特定の地域・ISP, サーバー全体
いつ 夜のピーク時間帯, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 パケットロスが集中したりPingが急上昇したりしたら画面にネットワーク状態を表示(同じ回線で大容量の転送が行われている可能性を案内)。
インフラチームの対応 データセンター回線の余裕を確保、自社の回線・スイッチポートのキューでの破棄(output drops)カウンターを確認、通信事業者の区間が詰まっていれば別の回線・ピアリングに迂回。
外部の対応 ユーザーにルーターのSQM(fq_codel、CAKE)とECNの利用を案内(キューがあふれる前に速度を落とさせる)、通信事業者にボトルネック区間の増強を依頼。
数値の目安 キューがあふれる瞬間には、数十msの間に入ってくるパケットのかなりの部分が一度に消えます。続けて失ったうえに送り直したパケットまで失いやすいため、RTOに至ることが多くなります。
グラフでは 特定の時間帯だけ高い · 再送率、RTT(Ping)
確認箇所 サーバーの再送率(nstatを1分間隔で実行して得たTcpRetransSegs ÷ TcpOutSegsの増分)と接続ごとのRTTを地域・通信事業者・時間帯別に分けて確認し、自社の回線・スイッチポートの出力破棄(ifOutDiscards)もあわせて確認。問題の地域に向けて、ピーク時間帯と空いている時間帯にmtrを取って比較 該当する場合 夜のピークにだけ再送率が上がり、パケットロスの直前にRTTが先に上がる(キューが埋まっていく様子)。mtrではピーク時間帯にだけ、ある区間から終点までパケットロスと遅延がそろって増える 該当しない場合 パケットロスの直前にRTTが上がらなければ「ポリサーによる超過分の破棄」。時間帯に関係なく常に同じようにパケットを失うなら「物理エラー」か「経路変更・ECMPの不良経路」 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 Riot Games 2015: 遠回りしていたLeague of LegendsのトラフィックとRiot Direct
出典9件
送信バーストによる浅いバッファのあふれ Sender bursts overflow shallow buffers
ID rt-burst · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ
サーバーがティックごとに数千人分の更新を一瞬でまとめて送ると、スイッチの小さなバッファやクラウドの瞬間的な上限が1ms足らずであふれ、一部が破棄されます。
なぜ ティックの開始時に、全員に送るパケットを一度に送信 → すると 複数のサーバーのトラフィックが集まるスイッチポートのバッファ(ポートあたり数百KB〜数MB)やクラウドインスタンスの上限が瞬間的にあふれる(平均利用率は低い) → 画面では 複数の人が同時にワープしたり一瞬止まったりする、平均値のメトリクスでは原因が見えない
症状 ワープ , フリーズ , 早送り
要因 パケットロス
誰に起きるか 特定の場所・チャンネル, サーバー全体
いつ 人が集中したとき
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ
ゲーム開発チームの対応 1ティック分の送信をティック内に分けて送る(数千の接続がティック開始時に集中するのは、接続ごとのペーシングではうまく解消しない)、サーバーごとにティックの開始時刻を分散、大きなデータを送る接続はSO_MAX_PACING_RATEで速度に上限を設定。
インフラチームの対応 サーバー機器・OS:サーバー全体の送信速度に上限を設定(サーバーOSのシェーパー、Linuxのtc)、1つの接続がまとめて送る分はペーシング(Linuxのfqキュー、BBR)で平準化。ネットワーク:バッファの大きいスイッチ、スイッチポートの出力破棄カウンターを短い間隔で確認(平均利用率では見えない)。
数値の目安 10Gbpsのポートが1msで送れる量は約1.25MBです。複数のサーバーのティックが重なって1つのポートに集中すると、バッファはあっという間に埋まります。
グラフでは 人数・負荷に連動して上昇 · スイッチポートの出力破棄数、再送率
確認箇所 サーバーがつながっているスイッチポートとその上位のポートの出力破棄(ifOutDiscards)を数秒間隔で収集し、クラウドならethtool -Sのbw_out_allowance_exceeded・pps_allowance_exceededを確認。同じ時刻の再送をbcc tcpretransで収集して突き合わせる 該当する場合 分単位の平均利用率は低いのに出力破棄やallowance超過が増え、その量が同時接続数や1か所に集まった人数に連動して大きくなる。再送が特定のユーザーのIPアドレス帯(通信事業者・地域)に偏らず、そのサーバーの複数の接続で同じ瞬間に起きる 該当しない場合 同じポートでCRC・入力エラーも増えていれば「物理エラー」。受信側サーバーのNICの破棄カウンターやsoftnetのdroppedが増えていれば「受信サーバーのホストでのパケット破棄」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく ペーシングは接続ごとに個別に動きます。数千の接続がティック開始時に1〜2個ずつ送ることで生じる集中は接続ごとのペーシングではうまく解消できないため、ゲームサーバーが送るタイミングを自分で分散させる必要があります。逆に1つの接続が大きなデータを送るときは、NICが数十KBのデータをパケットサイズに切り分けて続けて送り出しますが(TSO)、このような集中はペーシングがうまく分散してくれます。
出典7件
ID rt-policer · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
通信事業者の料金プラン、クラウドインスタンスの上限、DDoS対策機器は、決められた速度を超えるパケットをキューに入れずにすぐ破棄することもあります。
なぜ 瞬間的な送信量が許容速度・許容バーストを超える → すると 超えたパケットをキューに入れずにすぐ破棄(ポリシング) → 画面では バーストが大きい瞬間ごとに複数のパケットが消え、止まった後に早送り、平均速度は上限を下回って見える
症状 フリーズ , 早送り , ワープ
要因 パケットロス
誰に起きるか サーバー全体, 特定の地域・ISP, 自分だけ
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ティックごとにまとめて送る量をティック内に分けて送り、瞬間的な送信量を許容バースト以下に下げる、秒間パケット数の上限に引っかかるなら1ティック分のメッセージを1つのパケットにまとめる。
インフラチームの対応 ネットワーク:機器のポリサー超過カウンターを確認、ポリサーの代わりにシェーパーを使う、許容バーストを増やす。サーバー機器・OS:クラウドの上限超過メトリクス(AWSならethtool -Sのbw_out_allowance_exceeded・pps_allowance_exceeded)を確認、上位のインスタンスタイプへの変更、サーバーでのペーシング(Linuxのfqキュー)。
数値の目安 シェーパー(キューに入れて遅らせる)は遅延を増やし、ポリサー(すぐ破棄)はパケットロスを増やします。TCPのゲーム接続はパケットロス1回で数百ms止まることがあるため、上限を少し超える程度なら、たいていはポリサーのほうが影響が大きくなります。
グラフでは 上限で頭打ち · 短い間隔での送信量、ポリサー・allowance超過カウンター
確認箇所 ポリサーが設定された機器の超過(exceed)・破棄カウンターを確認し、クラウドならethtool -Sのbw_out_allowance_exceeded・pps_allowance_exceededを確認。パケットロスが起きた接続は、ss -tiのrttやパケットキャプチャでロス直前のRTTを確認 該当する場合 超過カウンターが増え、短い間隔で見た送信量がある値で切り取られたように平らになっている。パケットロスの直前にRTTが上がらず、バーストが大きい瞬間にだけ複数のパケットが一度に消える 該当しない場合 パケットロスの直前にRTTが先に上がればキューあふれ(「ボトルネックでのキューあふれ」「送信バーストによる浅いバッファのあふれ」)。超過カウンターが変わらなければ別の原因 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
ID rt-physical · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, 外部・外部
ケーブルの損傷、ほこりの付いた光コネクター、寿命を迎えた光モジュールはビットエラーを起こし、壊れたパケットは機器が黙って破棄します。
なぜ ケーブル・光モジュール・コネクターの不良でビットが反転 → すると チェックサム(CRC)が合わないパケットを機器が破棄 → 画面では その経路を通る人だけが継続的に一瞬止まっては早送り、時間帯とは無関係
症状 フリーズ , 早送り , ワープ
要因 パケットロス
誰に起きるか 特定の場所・チャンネル, 同じ家
いつ 常に
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, 外部・外部
インフラチームの対応 CRCエラーは壊れた方向の受信側で計上されるため、両端とも確認。ネットワーク:機器ポートのCRC・入力エラーカウンターを確認、光信号の強度を点検(スイッチの光モジュール情報)、光コネクターの清掃、ケーブル・光モジュールの交換。サーバー機器・OS:サーバーのethtool -Sのrx_crc_errors(ドライバーによって名前が少し違う)を確認、光信号の強度を点検(ethtool -m)、サーバー側のケーブル・NICの交換。
外部の対応 ユーザーの家の区間ならLANケーブル・ルーターの交換を案内、通信事業者の回線区間なら通信事業者に回線の点検を依頼。
数値の目安 パケットロスが0.1%でも、ゲームのパケット1,000個に1回です。その経路を通る人が数十人いれば、数秒ごとに誰かがカクッと止まります。ビットエラーは大きなパケットほど起きやすくなります。
グラフでは 一部だけ高い · ポートごとのCRCエラー数、サーバー・ポートごとの再送率
確認箇所 リンク両端のCRCカウンターを確認。サーバーはethtool -Sのrx_crc_errorsやip -s -s linkのcrc、スイッチはポートのFCSエラー(dot3StatsFCSErrors)・入力エラー(ifInErrors)。光リンクならethtool -mとスイッチの光モジュール情報で受信光強度を確認 該当する場合 1つのポートのCRCエラーが時間帯に関係なく継続的に増え、そのポートを通るサーバー・接続だけ再送率が高い。同じ種類の他のリンクより受信光強度が低い 該当しない場合 CRCは変わらないのに出力破棄だけが増えるならキューあふれ(「送信バーストによる浅いバッファのあふれ」「ボトルネックでのキューあふれ」)。片側のレイトコリジョンともう片側のCRCがそろって増えるなら「デュプレックスの不一致」 確認手段 インフラのツールで確認(ゲームコード不要)
出典3件
ID rt-duplex · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
片側はオートネゴシエーション、もう片側は速度・デュプレックスを固定にしておくと、片側が半二重で動作し、負荷がかかるたびに衝突(コリジョン)でパケットを失います。
なぜ 機器の片側だけ速度・デュプレックスを固定設定 → すると 片側は全二重、もう片側は半二重で動作し、コリジョン・レイトコリジョンが発生 → 画面では 普段は問題ないが、トラフィックが増えるとその機器を通る人全員が止まっては早送り
症状 フリーズ , 早送り
要因 パケットロス
誰に起きるか サーバー全体, 特定の場所・チャンネル
いつ 人が集中したとき, 夜のピーク時間帯
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
インフラチームの対応 両側ともオートネゴシエーション、または両側とも同じ値で固定。ネットワーク:スイッチポートの状態で速度・デュプレックスを確認、ポートカウンターで半二重側はレイトコリジョン、全二重側はCRCエラー・短すぎるフレーム(runt)が増えていないか確認。サーバー機器・OS:ethtoolで速度・デュプレックスを確認。
数値の目安 1Gbpsの銅線ケーブルはオートネゴシエーションが必須で、10Gbps以上には半二重そのものがありません。そのため最近は主に、100Mbps以下の古い機器、管理用ポート、一部の回線の接続区間で起きます。
グラフでは 人数・負荷に連動して上昇 · ポートのレイトコリジョン・CRCエラー数、再送率
確認箇所 リンク両側の実際の速度・デュプレックスを確認。サーバーはインターフェース名だけを付けて実行したethtool、スイッチはポートの状態やSNMPのdot3StatsDuplexStatus。レイトコリジョン(サーバーのtx_window_errors、スイッチのdot3StatsLateCollisions)とCRCエラーもあわせて確認 該当する場合 片側は半二重、もう片側は全二重と表示される。トラフィックが増えるたびに、半二重側はレイトコリジョン、全二重側はCRCエラーがそろって増える 該当しない場合 両側の速度・デュプレックスが同じでCRCだけが増えるなら「物理エラー」。10Gbps以上のリンクには半二重がないため、この原因からは除外 確認手段 インフラのツールで確認(ゲームコード不要)
出典6件
受信サーバーのホストでのパケット破棄 Receiver host drops (ring, softirq, CPU)
ID rt-host-drop · 主担当 インフラチーム・サーバーインフラ
パケットはサーバーまで届いたのに、NICのリングバッファ(到着したパケットを一時的に入れておくバッファ)があふれたり、カーネルで受信処理を担うコアが飽和したりして破棄されます。
なぜ 接続数の急増・1つのコアに集中した割り込み・仮想マシンのCPUスチール・仮想スイッチの過負荷 → すると リングバッファ(rx_missed_errorsなど、名前はドライバーによって異なる)やカーネルの受信キュー(softnet dropped)で破棄 → 画面では 人が集中すると、サーバー全体で同時に入力の反映が遅れ、一瞬止まる
症状 入力遅延 , フリーズ , 早送り , ワープ
要因 パケットロス, ストール
誰に起きるか サーバー全体
いつ 人が集中したとき
担当 主担当 インフラチーム・サーバーインフラ
インフラチームの対応 ethtool -Sのrx_missed_errorsのような破棄カウンターと/proc/net/softnet_statのdroppedを監視に追加、リングバッファのサイズを増やす(ethtool -G)、RSS・割り込みを複数のコアに分散、ゲームスレッドと受信処理のコアを分離、CPUの余裕を確保、仮想マシンならCPUスチール・仮想スイッチの負荷を確認。
数値の目安 サーバーが受信中に破棄したパケットは、クライアントが送り直します。そのためサーバーの再送メトリクスにはほとんど表れず、ethtool -Sのrx_missed_errorsのような破棄カウンター(名前はドライバーによって異なる)と/proc/net/softnet_statのdroppedに先に現れます。
グラフでは 上限で頭打ち · コアごとのsoftirq使用率、NICの破棄カウンター
確認箇所 ethtool -Sの破棄カウンター(rx_missed_errorsなど、mlx5ではrx_out_of_buffer・rx_discards_phy)、ip -s -s linkのmissed、/proc/net/softnet_statの2列目(dropped)・3列目(time_squeeze)を確認し、mpstat -P ALLでコアごとの%soft(ソフト割り込み処理)を確認。仮想マシンなら%stealも確認 該当する場合 人が集中する時刻に破棄カウンターやsoftnet droppedが増え、受信処理を担うコアの%softが100%近くで頭打ちになる。そのサーバーのすべての接続で同時に入力が遅れる 該当しない場合 サーバーの破棄カウンターが変わらず、再送が特定の地域・通信事業者の接続に集中するなら経路上のパケットロス。サーバーが送ったパケットを経路上で失った場合は、サーバーのnstat TcpRetransSegsが増え、これらのカウンターは変わらない 確認手段 インフラのツールで確認(ゲームコード不要)
出典10件
ID rt-stateful-fw · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ファイアウォールやLinuxの接続追跡(conntrack、通過する接続をテーブルに記録する機能)は、テーブルが満杯になったり、接続の状態が合わないと判断したりすると、パケットを破棄します。
なぜ 接続追跡テーブルが満杯(table full)、または行きと帰りの経路が異なり、片方向だけがファイアウォールを通る(非対称経路) → すると ファイアウォールが「知らない接続」や「ウィンドウの範囲から外れたシーケンス番号」のパケットとみなして破棄 → 画面では テーブルが満杯になると新規接続ができなくなり、経路がずれるとその経路の人だけが再送を繰り返した末に切断
症状 フリーズ , 切断 , 接続不可・無限ロード
要因 パケットロス
誰に起きるか サーバー全体, 特定の地域・ISP
いつ 人が集中したとき, 接続直後・メンテ明け, ときどきランダムに
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:テーブルが満杯になる場合に備え、ログイン待機列の仕組みで集中する接続を調整、短い接続を繰り返さないよう接続を再利用(サーバー間の呼び出しを含む)、ハートビートが途絶えた接続は先に整理。クライアント:接続に失敗したり切断されたりしたら、再試行間隔を延ばしながらランダムに分散(テーブルが満杯のときに一斉に再び殺到しないように)。
インフラチームの対応 ネットワーク:ファイアウォールの接続追跡テーブルのサイズを増やす、ゲームのポートは接続追跡から外す、行きと帰りの経路が同じファイアウォールを通るようルーティングを合わせる、ファイアウォールのTCPウィンドウ検査の設定を確認。サーバー機器・OS:Linuxのテーブルサイズを増やす(nf_conntrack_max)、ゲームのポートは接続追跡から外す(NOTRACK)、TCPウィンドウ検査の設定を確認(nf_conntrack_tcp_be_liberal)、AWSならconntrack_allowance_exceededも確認。
数値の目安 Linuxのconntrackの上限(nf_conntrack_max)のデフォルト値は、メモリ量に応じて数万〜数十万個です。現在の数(nf_conntrack_count)が上限に達すると、ログに「nf_conntrack: table full, dropping packet」が記録されます。
グラフでは 上限で頭打ち · conntrackのエントリ数(nf_conntrack_count)、新規接続の失敗数
確認箇所 Linuxサーバーではnf_conntrack_countとnf_conntrack_max、dmesgの「nf_conntrack: table full, dropping packet」、/proc/net/stat/nf_conntrackのdrop・invalid(コアごとに1行、16進数)を確認。ファイアウォールではセッションテーブルの使用量とドロップログ、AWSではethtool -Sのconntrack_allowance_exceededを確認 該当する場合 エントリ数が上限で平らになり、同じ時刻にtable fullのログとdrop、またはconntrack_allowance_exceededが増える。非対称経路の場合は上限に余裕があるのに、invalidとファイアウォールのドロップログが特定の経路の接続で増える 該当しない場合 エントリ数が上限から遠く、invalid・ドロップログも変わらなければ別の原因。テーブルには余裕があるのにファイアウォールのCPUや秒間パケット数が上限に達しているなら「中間機器の処理上限超過」 確認手段 インフラのツールで確認(ゲームコード不要)
出典5件
ID rt-appliance-pps · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
ファイアウォール、侵入防止システム(IPS)、DDoS対策機器は、通過するパケットを1つずつ検査します。検査能力を超えた瞬間から、処理しきれなかったパケットを破棄します。
なぜ ピーク時間帯・イベントで小さなゲームパケットが毎秒数十万個以上集中、または検査ルールが重い → すると 機器のCPU・秒間パケット数が上限に達し、機器で破棄。誤検知なら正常なパケットも遮断 → 画面では その機器の後ろにあるサーバー全体で同時にフリーズ・ワープ、人が集中したときだけひどくなる
症状 フリーズ , 早送り , ワープ , 切断
要因 パケットロス, 遅延
誰に起きるか サーバー全体, 特定の地域・ISP
いつ 夜のピーク時間帯, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 ゲームのトラフィックパターン(ポート、パケットサイズ、秒間パケット数)をインフラチームに共有、1ティックで送る小さなメッセージはまとめて一度に送り、パケット数を減らす。
インフラチームの対応 機器のCPU・秒間パケット数・ドロップカウンターをゲームのメトリクスと並べて確認、小さいパケットを基準に機器の容量を見積もる、ゲームのポートは重い検査から外す、DDoS対策のルールをゲームのトラフィックパターンに合わせる。
数値の目安 機器仕様の「10Gbps」は、1,500バイトの大きなパケットを基準に書かれていることが多いです。100バイト前後のゲームパケットは同じ帯域幅でもパケット数が10倍以上多くなるため、回線が空いて見えても秒間パケット数の上限が先に埋まります。
グラフでは 上限で頭打ち · 機器の秒間パケット数・CPU使用率、機器のドロップ数
確認箇所 機器のCPU・秒間パケット数・ドロップカウンターを確認し、機器の前後にあるスイッチポートのパケット数を同じ間隔で比較。同時接続数やサーバーの再送率と1つの画面に重ねて確認 該当する場合 ピーク・イベント時に機器の秒間パケット数やCPUがある値で頭打ちになり、機器に入ったパケットより出たパケットが少なくなる。同じ時刻に、その後ろのサーバー全体の再送率もそろって上がる 該当しない場合 機器の前後のパケット数が同じで、機器でのドロップもなければ別の原因。サーバーのNICの破棄カウンターやsoftnet droppedが増えていれば「受信サーバーのホストでのパケット破棄」 確認手段 インフラのツールで確認(ゲームコード不要)
出典1件
ID rt-mtu · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
途中の区間が受け取れるサイズが小さくなったのに「大きすぎる」という通知(ICMP)が遮断されると、大きなパケットは何度送り直しても消え続けます。
なぜ VPN・トンネル区間で最大サイズが小さくなり、サイズ超過の通知はファイアウォールで遮断 → すると 送信側は理由がわからないまま同じ大きなパケットを再送し続け、RTOは2倍ずつ増加 → 画面では 普段は問題ないが、インベントリ・人の多い場所・入場時のロードのように大きなデータがやり取りされる瞬間に、後続の小さなパケットまですべて止まり、最終的に切断や無限ロード
症状 フリーズ , 切断 , 接続不可・無限ロード
要因 パケットロス
誰に起きるか 特定の地域・ISP, 自分だけ
いつ 特定の操作をしたとき, 接続直後・メンテ明け
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 サーバー側で直接下げるならソケットの最大セグメントサイズ(TCP_MAXSEG)を設定、ゲームコードでメッセージを細かく分割するだけでは防げない(TCPが送るデータをMSSのサイズでまとめ直すため)。
インフラチームの対応 ネットワーク:境界の機器でMSSを調整(clamping)、ファイアウォール・クラウドのネットワークACLでサイズ超過のICMP(タイプ3コード4、fragmentation needed)を許可。サーバー機器・OS:経路MTUの設定、サーバーのファイアウォール・クラウドのセキュリティグループでもサイズ超過のICMPが遮断されていないか確認、最後の安全策としてLinuxのtcp_mtu_probing=1。
数値の目安 通常は1,500バイトで、トンネルを通ると1,400前後です。同じパケットが5〜6回再送されると、止まる時間は10秒を超えます。
グラフでは 一部だけ高い · 接続ごとのRTO・backoff、地域・通信事業者ごとの切断数
確認箇所 問題の接続の再送をサーバー側のパケットキャプチャやbcc tcpretrans -s(シーケンス番号を表示)で確認し、ss -tiでその接続のmss・pmtu・backoffを確認。サーバーからそのユーザーのアドレスに、小さなpingとDFを立てた1,500バイトのping(ping -M do -s 1472)を送って比較 該当する場合 MSSいっぱいのパケットが同じシーケンス番号で、間隔を2倍ずつ延ばしながら再送され続け、それより小さなパケットは届く。サイズ超過のICMP(Wiresharkのフィルターicmp.type == 3 and icmp.code == 4)は届かず、小さなpingには応答があるのに、大きなDF付きのpingだけが応答なく消える 該当しない場合 小さなパケットも一緒に消えるなら、サイズと関係ないパケットロス(「ボトルネックでのキューあふれ」「経路変更・ECMPの不良経路」)。サイズ超過のICMPが届き、ss -tiのpmtuが小さくなるなら、経路MTU探索は正しく動作している 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく tcp_mtu_probing=1は、再送タイムアウトが数秒(tcp_retries1=3に相当)続いた後になって初めてブラックホールと判断し、MSSを1,024バイトに下げます。その間は止まったままになるため、これは最後の安全策にとどめ、事前に防ぐMSSの調整を先に行います。
出典15件
ID rt-mapping · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ, インフラチーム・サーバーインフラ
アイドル接続のマッピング(この接続をどこに転送するかを記録したエントリ)を中間機器が消すと、次に送るパケットは転送されません。再送だけを繰り返した末に切断されるか、機器が接続拒否(RST)を返してすぐに切断されます。
なぜ しばらくパケットのやり取りがない接続(離席、ロビー) → すると ルーターのNAT・通信事業者のCGNAT・ファイアウォール・ロードバランサー・クラウドのセキュリティグループがアイドル状態のマッピングを削除 → 画面では 再び動いた瞬間に再送が続いた末に切断、またはすぐに切断
症状 切断 , フリーズ
要因 パケットロス
誰に起きるか 自分だけ, 特定の地域・ISP
いつ しばらく放置した後
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ, インフラチーム・サーバーインフラ
ゲーム開発チームの対応 クライアント:最も短いアイドルタイムアウトの半分以下の間隔でハートビートを送る(ユーザーのルーター・通信事業者のCGNATのマッピングは内側から出ていくパケットでしか確実に更新されず、そのタイムアウトは自社では変えられないため、クライアントが送る)、切断されたら自動で再接続。サーバー:ハートビートに応答し、一定時間受信できなければ接続を先に整理(TCP keepaliveの間隔を縮める(TCP_KEEPIDLEなどのソケットオプション)、TCP_USER_TIMEOUTで早く検知)、セッショントークンで引き継ぐ。
インフラチームの対応 ネットワーク:経路上のファイアウォール・ロードバランサーのアイドルタイムアウトをまとめてゲーム開発チームに共有、自社のファイアウォール・ロードバランサーは必要なら延ばす。サーバー機器・OS:クラウドのセキュリティグループの接続追跡時間を確認してゲーム開発チームに共有。
数値の目安 TCPのマッピングを保持する時間は、機器によって数分から数時間までまちまちです。クラウドのセキュリティグループが接続を追跡する設定の場合、AWSのNitro v6インスタンスタイプはデフォルトで350秒後に追跡エントリを削除します(その他のタイプは5日、「クラウドのセキュリティグループによる接続追跡の期限切れ」の項目を参照)。LinuxのTCP keepaliveはデフォルト値が「2時間アイドルなら確認」なので、ほとんどの機器より遅くなります。
グラフでは 接続が一斉に切れる · 切断数、切断前のアイドル時間
確認箇所 切断された接続の最後の数分をサーバー側のパケットキャプチャで確認し、生きている接続はss -tiのlastsnd・lastrcv(最後に送信・受信してから経過したms)でアイドル時間を確認。nstatのTcpExtTCPAbortOnTimeout(タイマーが切れて接続をあきらめた数)もあわせて確認 該当する場合 切断された接続はどれも、直前のアイドル時間が同じような値(経路上の機器のアイドルタイムアウト、例:AWS Nitro v6インスタンスのセキュリティグループの350秒)を超えており、アイドル後の最初のパケットからACKのない再送だけが続いてあきらめるか、すぐにRSTが返ってくる 該当しない場合 アイドル時間と関係なくプレイ中にも切断されるなら別の原因(「経路変更・ECMPの不良経路」「ファイアウォール・接続追跡による破棄」)。ハートビートが最も短いアイドルタイムアウトの半分以下の間隔でやり取りされている接続なら、この原因からは除外 確認手段 インフラのツールで確認(ゲームコード不要)
出典8件
経路変更・ECMPの不良経路 Route change / bad ECMP member
ID rt-path · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
インターネットの経路が切り替わる数秒の間、または複数のECMP経路のうち不良な経路に割り当てられた接続で、パケットが消えます。
なぜ BGPの経路再計算、または複数の経路(ECMP・LAG)のうち1つの経路で機器・回線が不良 → すると 経路の切り替え中に一時的なパケットロス、またはその経路を通る接続だけに継続的なパケットロス → 画面では 突然数秒止まった後に早送り、または「再接続すると直る」(別の経路に割り当てられる)
症状 フリーズ , 早送り , ワープ
要因 パケットロス
誰に起きるか 特定の地域・ISP
いつ ときどきランダムに
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
ゲーム開発チームの対応 接続ごとの再送統計(TCP_INFO)を記録し、症状が出ている人のIP・ポートと時刻を抽出できるようにする、数秒止まった接続をすぐに切断しない。
インフラチームの対応 地域・通信事業者ごとの再送率を監視、再接続で経路が変わるかを確認、複数の通信事業者の回線を確保、自社機器のECMP・LAG経路のうち不良リンクを点検、経路の測定もゲームと同じTCPポートで行う(mtr --tcp --port。経路はアドレス・ポートで決まるため、通常のpingは別の経路を通って正常に見えることもある)。
外部の対応 通信事業者に、同じTCPポートで測った経路の測定結果と再接続前後の比較を添えて、不良経路を報告。
グラフでは ある時点から階段状に上昇 · RTT(Ping)、地域・通信事業者ごとの再送率
確認箇所 bcc tcpretrans -cで再送を接続ごとに集計し、症状が出ているユーザーのアドレス・ポートを抽出。サーバーからユーザー側へ、ユーザー側からサーバーへ、ゲームと同じTCPポートでmtr(mtr -T -P PORT)を取って比較。再接続の前後の結果も比較 該当する場合 ある時刻を境に、特定の地域・通信事業者のRTTが階段状に変わって数秒間パケットロスが集中する。または同じ通信事業者の中でも一部の接続(アドレス・ポートの組み合わせ)だけが継続的に再送し、再接続すると直る。通常のpingは正常なのに、TCPのmtrでだけパケットロスが見えることもある 該当しない場合 その通信事業者のすべての接続が夜のピークにそろって悪化するなら「ボトルネックでのキューあふれ」。1人のユーザーだけが悪く、ルーターまでのpingからパケットロスがあるなら「無線区間のパケットロス」 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 Cloudflare 2020: Cloudflareのバックボーン設定ミスで一部都市のトラフィックが途絶
出典5件
遅延の急上昇による不要な再送 Spurious RTO from delay spikes
ID rt-spurious-delay · 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
パケットは消えておらず、一時的にとても遅れて届いただけなのに、その遅延がRTOより長いと、送信側はパケットロスと判断して再送します。
なぜ バッファブロート、Wi-Fiの省電力、モバイルの無線状態の切り替え、仮想マシンの一時停止で、瞬間的な遅延が数百ms → すると RTOが先に満了して再送、元のパケットもすぐに到着(受信側は重複して受け取る) → 画面では フリーズ・早送りは遅延の急上昇そのものが原因。不要な再送は止まる時間をほとんど延ばさず、再送のメトリクスだけを押し上げるため、パケットロスと誤解される
症状 フリーズ , 早送り , 入力遅延
要因 遅延, ジッター
誰に起きるか 自分だけ, サーバー全体
いつ ときどきランダムに, しばらく放置した後
担当 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 Android 10以上のクライアントは、ゲーム中に低遅延Wi-Fiモード(WIFI_MODE_FULL_LOW_LATENCYのWi-Fiロック、画面がオンでゲームがフォアグラウンドにあるときだけ適用)を要求し、省電力による遅延の急上昇を減らす。
インフラチームの対応 バースト可能インスタンスを避ける、RTOの最小値を下げすぎない、F-RTO・タイムスタンプを維持(tcp_frto、tcp_timestamps)、再送のメトリクスはnstatのTCPSpuriousRTOs・TCPDSACKRecvとあわせて確認し、パケットロスと誤解しない。
外部の対応 遅延の急上昇そのものを減らすため、ユーザーにルーターのSQMの利用、Wi-Fiの省電力の無効化を案内。
数値の目安 LinuxはF-RTOで不要なRTOを検知し、送信量の絞り込みを元に戻すこともあります。nstatのTCPSpuriousRTOs(不要なRTOと判定した回数)とTCPDSACKRecv(受信側が「もう受け取った」と知らせてきた回数)で確認します。
グラフでは 不定期なスパイク · RTT(Ping)、不要なRTOの数
確認箇所 nstatを1分間隔で実行し、TcpExtTCPTimeouts(RTOの満了)、TcpExtTCPSpuriousRTOs、TcpExtTCPDSACKRecv、TcpExtTCPLostRetransmitの増分をあわせて確認。パケットキャプチャがあれば、Wiresharkのフィルターtcp.analysis.spurious_retransmissionを使う 該当する場合 RTOが増えるときにTcpExtTCPSpuriousRTOsやTcpExtTCPDSACKRecvもそろって増え、同じ時刻にRTTが数百msに跳ねる。受信側のキャプチャに、元のパケットと再送の両方が届いている 該当しない場合 TcpExtTCPSpuriousRTOs・DSACKは変わらないのにTcpExtTCPLostRetransmit(送り直したものまでまた失う)が増えるなら実際のパケットロス。RTTは跳ねないのにDSACKだけが継続的に多いなら「順序の入れ替わりによる不要な高速再送」 確認手段 インフラのツールで確認(ゲームコード不要)
出典11件
順序の入れ替わりによる不要な高速再送 Reordering triggers spurious fast retransmit
ID rt-reorder · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
複数の経路や束ねたリンクを通る間にパケットの順序が入れ替わると、受信側が重複ACKで「抜けたパケットがある」と知らせ、送信側は問題のないパケットを送り直します。
なぜ パケット単位で経路を振り分ける機器、パケット単位で振り分けて送るLAG(リンクアグリゲーション)、経路が切り替わる瞬間が順序を乱す → すると 後のパケットが先に到着して重複ACKが3つたまる → 高速再送 → 画面では まばらにやり取りされるゲームパケットにはほとんど影響なし。人の多い場所での大きな更新やアップデートデータのダウンロードが遅くなり、ときどきカクつく
症状 カクつき , 入力遅延
要因 ジッター
誰に起きるか 特定の地域・ISP, サーバー全体
いつ 常に, 人が集中したとき
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
インフラチームの対応 ネットワーク:パケット単位の分散の代わりに接続単位の分散(ECMP・LAGをアドレス・ポートのハッシュで)。サーバー機器・OS:RACK(時間に基づくロス判定、順序の入れ替わりに強い。DSACKで不要な再送を検知すると、順序の入れ替わりの許容幅を自動で広げる)を使う、Linuxが接続ごとに自動で推定した順序の入れ替わりの度合いを確認(ss -tiのreordering値、初期値はtcp_reordering=3)。
グラフでは 最初から常に高い · 順序の入れ替わりの検知数、DSACKの受信数
確認箇所 nstatのTcpExtTCPSACKReorder・TcpExtTCPTSReorder(順序の入れ替わりを検知した回数)とTcpExtTCPDSACKRecvを確認し、接続ごとにはss -tiのreordering(3でなければ表示)・reord_seenを確認。パケットキャプチャでは、Wiresharkのフィルターtcp.analysis.out_of_orderを使う 該当する場合 順序の入れ替わりのカウンターとDSACKが時間帯に関係なく継続的に増え、特定の経路・機器を通る接続のreordering値が3より大きくなっている。受信側のキャプチャで、後のパケットが先に届き、前のパケットもすぐに届いている 該当しない場合 順序の入れ替わりのカウンターは変わらず、TcpExtTCPLostRetransmitが増えるなら実際のパケットロス。RTTが跳ねる瞬間にだけDSACKが増えるなら「遅延の急上昇による不要な再送」 確認手段 インフラのツールで確認(ゲームコード不要)
出典9件
ACKの遅れ・消失(上り回線の飽和) ACK path congestion on asymmetric links
ID rt-ack-path · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
データは問題なく届いているのに、「受け取った」というACKが満杯の上りキューで遅れたり消えたりすると、送信側はパケットロスと判断して再送します。
なぜ 家で動画のアップロード・クラウドバックアップにより上り回線が満杯 → すると ACKがルーターのキューで数百ms遅れるか、あふれて破棄される → 画面では サーバーが送るゲームパケットはおおむね時間どおりに届く。同じ上りキューにたまった自分の入力が遅れて入力遅延・引き戻し、ときどき不要な再送
症状 入力遅延 , 引き戻し
要因 遅延, パケットロス
誰に起きるか 同じ家
いつ ときどきランダムに, 夜のピーク時間帯
担当 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 Pingが急上昇したら画面にネットワーク状態を表示、「アップロード中のプログラムを確認」という案内を表示。
外部の対応 ユーザーに、ルーターのSQMで上りキューを短くする、小さなパケット(ACK)を優先処理する、アップロード速度を制限する(動画のアップロード・クラウドバックアップ)ことを案内。
数値の目安 ACKは後のACKが前のものの分まで確認してくれるため、いくつか消えるのはたいてい問題ありません。問題になるのは、キューで遅れるほうです。
グラフでは 一部だけ高い · 接続ごとのRTT(Ping)
確認箇所 ユーザーのPCで、アップロード(動画のアップロード・クラウドバックアップ)を実行した状態と止めた状態で、ゲームサーバーへのpingを比較。サーバーではss -tiでそのユーザーの接続のrttを確認 該当する場合 アップロード中にだけpingが数百msに上がって入力遅延・引き戻しが起き、アップロードを止めるとすぐに戻る。サーバーから見ると、そのときその接続のrttもそろって上がる 該当しない場合 アップロードと関係なくパケットロスと遅延が起きるなら「無線区間のパケットロス」か経路側の原因。サーバーからユーザーへの方向だけが遅く、アップロードと関係ないなら「ボトルネックでのキューあふれ」 確認手段 ユーザー側の環境で確認
出典4件
ID rt-rto-setting · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
RTOの最小値を下げすぎると少し遅れただけで不要な再送が起き、デフォルト値(200ms)はゲームにとっては長すぎて、1回失うたびに長く止まります。
なぜ データセンター向けにRTOの最小値を大きく下げた、またはインターネット区間でデフォルト値のまま使用 → すると 低いと瞬間的な遅延でも再送が殺到、高いとパケットロスのたびに長く待つ → 画面では デフォルト値ならパケットロス1回で数百ms止まった後に早送り、下げすぎると止まる時間は減るが不要な再送が急増して回線を浪費
症状 フリーズ , 早送り , 入力遅延
要因 遅延
誰に起きるか サーバー全体
いつ 常に
担当 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 Linux 6.15以降なら、ゲームの接続にTCP_RTO_MAX_MSでRTOの上限を下げることを検討(あきらめるまでの時間も短くなるため、TCP_USER_TIMEOUTで切断と判定する時間も一緒に決める)、サーバー間の内部接続だけソケットオプションTCP_RTO_MIN_US(6.15以降)でRTOの最小値を下げる、ソケットオプションTCP_THIN_LINEAR_TIMEOUTSでゲームの接続だけ連続したRTOが2倍に延びないようにすることを検討。
インフラチームの対応 サーバー間の内部接続だけ経路ごとにrto_minを下げる、インターネット区間はデフォルト値を維持しつつRACK-TLP・thin streamの設定(tcp_thin_linear_timeouts)で補う。
数値の目安 LinuxのRTO = 往復時間 + max(200ms, RTTの偏差×4)。失敗するたびに2倍になり、最大120秒です。Linux 6.15以降は、TCP_RTO_MAX_MSでこの上限を1秒まで下げられます。
グラフでは 最初から常に高い · 接続ごとのRTO、不要なRTOの数
確認箇所 サーバーのRTO最小値の設定(ip route showのrto_min、Linux 6.11以降はsysctl net.ipv4.tcp_rto_min_us)とss -tiのrto・rttを確認し、nstatのTcpExtTCPSpuriousRTOsの増分を確認 該当する場合 最小値を下げたサーバーで、インターネット接続のrtoがrttにぴったり張り付いており、TcpExtTCPSpuriousRTOsが大きく増える。デフォルト値のままなら、ゲームの接続のrtoがrttより200ms以上大きく、パケットロス1回ごとにその分止まる 該当しない場合 rtoがデフォルトの計算どおり(rtt + 200ms前後)で不要なRTOも少ないのに、止まる時間が際立って長いなら、連続したパケットロスか回復方式側の問題(「thin streamの遅い回復」「中間機器によるTCPオプションの除去」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典12件
ID rt-thin · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲームのように小さなパケットをまばらに送ると、「後続のパケット3つ」がそろう前にRTOが先に来ます。大容量の転送と比べて、同じパケットロスでもはるかに長く止まります。
なぜ パケットの間隔が100ms前後なので、ACK待ちのパケット(in-flight)が数個しかない → すると 重複ACKが3つそろうには300ms以上かかるため、RTO(Ping + 200ms)が先に発動、連続したパケットロスなら2倍ずつ → 画面では パケットロス1回で0.3秒前後止まり、送り直したものまで失うと1秒近く止まった後に早送り
症状 フリーズ , 早送り
要因 パケットロス, ストール
誰に起きるか 自分だけ, サーバー全体
いつ ときどきランダムに
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:TCP_NODELAYを有効にする(Nagleアルゴリズムが有効だと、RACKが判定に使う後続パケットがない)、リアルタイムのパケットはUDP上の独自の再送で。クライアント:TCP_NODELAYを有効にする、リアルタイムのパケットはサーバーと同じ方式(UDP)で。
インフラチームの対応 RACK-TLPを使う(最新Linuxのデフォルト)、tcp_thin_linear_timeoutsで連続したRTOが2倍に延びないようにする。
数値の目安 パケット間隔が100ms、Pingが60msなら、高速再送までは約360ms(後続のパケット3つが届き、その確認応答が戻ってくるまで)、RTOは約260msです。RACKを使えば、次のパケットの確認応答が戻ってくる約160msの時点ですぐに送り直します。パケット間隔が200msを超えると、RACKでもRTOより速くはなりません。
グラフでは 途切れた後にまとめて到着 · 接続ごとの受信量、RTOの満了数
確認箇所 nstatのTcpExtTCPTimeouts(RTOの満了)・TcpExtTCPFastRetrans(高速再送)・TcpExtTCPLossProbes・TcpExtTCPLossProbeRecovery(TLP)の増分を比較し、ゲームの接続をss -tiで見てrto・backoffを確認。サーバーのnet.ipv4.tcp_recovery・tcp_early_retrans・tcp_sackの値も確認 該当する場合 再送のうちRTOの満了が高速再送より多く、ゲームの接続でbackoffが0より大きい状態(RTOの最中)がよく見られる。止まっている間の受信量が0で、回復すると一気にまとめて届く 該当しない場合 同じサーバーの大容量の転送も同じように長く止まるなら、通信パターンとは関係ないパケットロスの問題。SACK・タイムスタンプのない接続に偏るなら「中間機器によるTCPオプションの除去」 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく Linuxには以前、thin stream向けに重複ACK1つで再送するオプション(tcp_thin_dupack)もありましたが、2017年に廃止され、今はRACKがその役割を担っています。Nagleアルゴリズムが有効だと(TCP_NODELAYが無効)、失ったパケットの確認応答を待つ間は新しいパケットも送らないため、RACKが判定に使う後続パケットがなく、RTOまで待つことになります。
出典11件
ID rt-sack-stripped · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
一部のファイアウォール・高速化装置がTCPオプションを消したり書き換えたりすると、複数のパケットを失ったときに1往復に1つずつしか回復できなくなったり、ウィンドウ(一度に送れる量)が小さくなったりして遅くなります。
なぜ ファイアウォールの「TCP正規化」、古い高速化装置がSACK・タイムスタンプ・ウィンドウスケールのオプションを除去 → すると 失ったパケットが複数あると1往復ごとに1つずつ回復、ウィンドウは64KBに制限される → 画面では パケットロスのたびに止まる時間がずっと長くなり(SACKがないとRACK-TLPも使えない)、解消すると早送り。アップデートデータのダウンロードのような大容量の転送も遅い
症状 フリーズ , 早送り
要因 ストール, 遅延
誰に起きるか 特定の地域・ISP, サーバー全体
いつ 常に
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
インフラチームの対応 ネットワーク:該当機器のTCP正規化の設定を無効にする、ファイアウォールのシーケンス番号ランダム化も確認、両端のパケットキャプチャでSYNのオプションを比較。サーバー機器・OS:ss -tiでsack・wscaleの表示がない接続が特定の経路に偏っていないか確認(tsはWindows PCが設定によって使わないため、tsだけがないのは正常な場合がある)、サーバーのnet.ipv4.tcp_sackが1になっているか確認。
グラフでは 最初から常に高い · SACKなしで開始した回復の数(TcpExtTCPRenoRecovery)
確認箇所 ss -tiで接続ごとにsack・wscaleの表示があるかを確認し、nstatのTcpExtTCPRenoRecovery(SACKなしで開始した回復)とTcpExtTCPSackRecoveryの比率、TcpExtTCPSACKDiscard(整合しないため破棄したSACKブロック数)を確認。疑わしい経路は両端でSYNをキャプチャし、オプション(Wiresharkのtcp.options.sack_permなど)を比較 該当する場合 特定の経路・機器を通る接続だけsack・wscaleがなく、TcpExtTCPRenoRecoveryの割合が高い。送信側でキャプチャしたSYNにあったSACK許可オプションが、受信側でキャプチャしたSYNにはない。シーケンス番号ランダム化が原因なら、オプションは残っているのにTcpExtTCPSACKDiscardが増える 該当しない場合 すべての接続でsackがないなら、まずサーバーのnet.ipv4.tcp_sackの値を確認。オプションがそろっていてTcpExtTCPSACKDiscardも変わらなければ、回復が遅い理由は別にある(「thin streamの遅い回復」) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく オプションが残っていても、SACKが壊れることがあります。ファイアウォールのシーケンス番号ランダム化(sequence randomization)がヘッダーのシーケンス番号だけを書き換え、SACK内の番号をそのままにすると、送信側は整合しないSACKを破棄します。2019年のSACKの脆弱性の際にサーバーでtcp_sack=0にして無効化し、そのまま忘れている場合も結果は同じです。
出典10件
ゼロウィンドウ(再送のように見える停止) Zero window, often mistaken for retransmission
ID rt-zero-window · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・サーバーインフラ
受信側のプログラムがソケットを読むのが間に合わず、バッファが満杯になると、送信側は送信を止めてゼロウィンドウプローブだけを送ります。回線の問題ではありません。
なぜ クライアントのフレームが止まる、サーバーのスレッドがブロックされるなどでソケットを読めない → すると 受信ウィンドウが0になり、送信側は送信を止めてプローブだけを送る(間隔がだんだん延びる) → 画面では 止まった後に早送り。パケットキャプチャに「ZeroWindow」が見え、パケットロスはない
症状 フリーズ , 早送り
要因 ストール
誰に起きるか 自分だけ, サーバー全体
いつ 人が集中したとき, ときどきランダムに
担当 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・サーバーインフラ
ゲーム開発チームの対応 パケットキャプチャでZeroWindowを送った側(ソケットを読めていない側)をまず確認、ネットワークの受信は別スレッドで読み続ける、受信バッファを適切なサイズに。クライアント:ロード・GCのようなフレーム停止の原因を解消。サーバー:ソケットを読むスレッドがブロックされる原因を解消。
インフラチームの対応 サーバーのnstat TcpExtTCPToZeroWindowAdv(サーバーが受信ウィンドウを0と通知した回数)を監視に追加(増えればサーバー側の問題なのでサーバー開発に連絡)、サーバー側のパケットキャプチャを提供。
グラフでは 途切れた後にまとめて到着 · 接続ごとの受信量、ゼロウィンドウの回数
確認箇所 パケットキャプチャでWiresharkのフィルターtcp.analysis.zero_windowを使い、ウィンドウ0を通知した側を探す。サーバーのnstatでは、TcpExtTCPToZeroWindowAdv(サーバーがウィンドウ0を通知)とTcpExtTCPWinProbe(相手のウィンドウ0に対してプローブを送信)を分けて確認し、サーバーのソケットのRecv-Q(ssで表示される、プログラムがまだ読んでいないバイト数)を確認 該当する場合 止まっている間に再送はなく、ゼロウィンドウとプローブだけがやり取りされる。サーバーのTcpExtTCPToZeroWindowAdvやサーバーのソケットのRecv-Qが増えるならサーバーの読み出しが間に合っていない。TcpExtTCPWinProbeが増えるならクライアントの読み出しが間に合っていない 該当しない場合 キャプチャにゼロウィンドウがなく、同じデータが再度送られているなら、原因はパケットロスか不要な再送 確認手段 インフラのツールで確認(ゲームコード不要)
実際の事例 Roblox 2021: Robloxの73時間障害:サービスディスカバリ(Consul)クラスターでの競合
出典7件
接続要求(SYN)の再送 SYN retransmission on connect
ID rt-syn · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ, ゲーム開発チーム・クライアント開発
接続要求が接続待ちキュー(backlog)のあふれやファイアウォールの遮断で消えると、クライアントOSは1秒後から間隔を延ばしながら送り直します。
なぜ メンテ明けの接続の殺到でサーバーの接続待ちキューがあふれる、またはファイアウォール・DDoS対策がSYNを破棄 → すると クライアントOSが1秒後から決まった間隔でSYNを再送(以前のLinuxは1秒 → 2秒 → 4秒) → 画面では 接続ボタンを押してから1秒、3秒のようにきりのいい秒数だけ遅れ、失敗が続くと接続不可・無限ロード
症状 接続不可・無限ロード
要因 パケットロス
誰に起きるか サーバー全体, 特定の地域・ISP
いつ 接続直後・メンテ明け
担当 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応 サーバー:listenのbacklog引数を増やす(somaxconnとあわせて)、ゲームサーバーがacceptを遅れずに呼ぶようにする、ログイン待機列の仕組み。クライアント:接続の再試行間隔を延ばす(ランダムに分散)。
インフラチームの対応 サーバー機器・OS:サーバーの接続待ちキューのあふれはnstatのTcpExtListenOverflows・TcpExtListenDropsとログの「Possible SYN flooding」警告で確認、somaxconnを増やす(listenの引数とあわせて)、SYN Cookie。ネットワーク:ファイアウォール・DDoS対策のSYN制限を緩和。
数値の目安 Linux(Androidを含む)の最初のSYN再送は1秒後です。以前のカーネルはその後間隔を2倍ずつ延ばし、1、3、7、15秒…の時点で再送、6.5以降は1、2、3、4、5秒の時点で5回送り直した後に2倍ずつ(7、11、19秒…)間隔を延ばします(tcp_syn_linear_timeouts=4)。Androidスマホは、OSをアップデートしても発売時のカーネルを使い続けることが多いため、同じAndroidバージョンでも端末ごとに異なる場合があります。どちらの場合も、すべて失敗すると約2分後にあきらめます。Windowsはバージョンと設定によって1秒または3秒から延びていき、送り直す回数が2〜4回なので20〜30秒であきらめます(そのPCの値はnetsh int tcp show globalのMax SYN Retransmissionsで確認)。
グラフでは 接続直後・メンテ明けに急増 · 接続試行数、接続待ちキューのあふれ数
確認箇所 サーバーのnstatでTcpExtListenOverflows・TcpExtListenDropsとdmesgの「Possible SYN flooding on port」警告を確認し、ss -lntで待ち受けソケットのRecv-Q(acceptを待っている接続数)がSend-Q(backlogの上限)に達していないか確認。サーバー側のキャプチャで、SYNが届いているか、SYN-ACKを返しているかを確認 該当する場合 メンテ明けの接続殺到時にTcpExtListenOverflowsが増え、Recv-QがSend-Qに張り付いている。キャプチャでは、同じクライアントのSYNが秒単位の間隔で再び届いているのに、サーバーが応答しない 該当しない場合 SYNがサーバーまで届かず、サーバーのカウンターも変わらないなら、前段のファイアウォール・DDoS対策が破棄しているので、その機器のSYN制限・ドロップログを確認。サーバーがSYN-ACKを送っているのに接続が遅いなら、戻り方向のパケットロス 確認手段 インフラのツールで確認(ゲームコード不要)
出典11件
状況別の手順
アップデート後のラグ 特定のアップデート・デプロイの後からラグ報告が増えたとき。「今回のアップデートからおかしい」という報告が集まったときや、グラフがある時刻から階段状に上がって高止まりしている場合に使う。
開始時刻を確定し、その前後の変更をすべて集める : 報告が最初に集中した時刻と、グラフが階段状に上がった時刻を特定し、その前後に入った変更を漏れなく書き出す。クライアントのアップデート、サーバーのデプロイ、設定変更、DBのスキーマ変更(DDL)と再起動、ネットワーク・ファイアウォールの作業、インフラの入れ替え(インスタンスタイプ・カーネル・ドライバー)をあわせて確認する。デプロイのたびに監視ツールの注釈(annotation)機能ですべてのグラフに縦線を残しておけば、このステップはすぐに終わる。ゲームのアップデートとインフラ作業が同じメンテナンスで行われていたなら、両方を候補に残す。最初に呼ぶ担当:変更を入れたゲーム開発チームとインフラチームの両方。 (デプロイ・再起動 , OS・カーネル・ドライバー・ファームウェアのアップデート後の性能変化 , サービス中のスキーマ変更(DDL)によるロック , 実行計画の変化によるクエリ遅延 , コールドキャッシュ(再起動直後) ) 範囲を切り分ける:ビルド・端末・サーバー・地域 : 異常がどの軸に偏っているかを確認する。新しいビルドのユーザーだけが悪ければクライアント、特定のOS・グラフィックカード・端末だけならクライアントの性能やドライバー、特定のサーバー・チャンネル・ゾーンだけならサーバー、特定の国・通信事業者だけならネットワーク経路、全員が同時に悪ければ共有リソース(DB・ロードバランサー・ゲートウェイ)か直前のサーバーデプロイを、まず疑う。クライアントのテレメトリにビルド番号があれば、旧ビルドと新ビルドのPing・FPS・フレームスパイク・切断回数を並べて比較する。Pingは変わらずFPSだけが悪化したなら、ネットワークよりもクライアントの性能の問題だ。最初に呼ぶ担当:ビルド・端末に偏るならゲーム開発チーム(クライアント)。サーバー・チャンネルに偏るなら、ホストのメトリクスが正常な場合はゲーム開発チーム(サーバー)、異常な場合はインフラチーム(サーバー機器・OS)。国・通信事業者に偏るならインフラチーム(ネットワーク)。 (フレームタイムのスパイク , メインスレッドでの同期ロード・シェーダーコンパイル , ビデオメモリ(VRAM)不足 , クライアントのクラッシュ ) 新旧バージョンを同じ時間帯で比較する : デプロイ前後の比較だけでは、曜日・時間帯・イベントによる変化が混ざり、判断がぶれる。可能なら新バージョンを一部のサーバー(カナリア)に先に入れ、同じ時間帯の旧バージョンのサーバー(対照群)と、ティック時間のp50・p99、ティック超過回数、CPU、メモリ、エラー率を並べて比較する。すでに全体にデプロイ済みなら、先週の同じ曜日・同じ時間帯と比較する。サーバー全体の平均だけでは一部のサーバー・ゾーンの問題が埋もれるので、サーバー・ゾーン別に分けて確認する。最初に呼ぶ担当:ゲーム開発チーム(サーバー)。 (ティックバジェット超過 , アロケーションの急増 , メモリリーク , ブロードキャストの急増 ) トラフィックのフィンガープリントを前後で比較する : サーバーのコードを知らなくても、ネットワーク側から見える値で、アップデートがトラフィックの形を変えたかどうかを確認する。ユーザーあたりの秒間パケット数(pps)とバイト数、平均・最大パケットサイズ、接続数、ティックごとに一気に送り出される送信バーストの大きさを前後で比較する。UDPパケットが経路MTU(通常1,500バイト)を超え始めたなら、IPフラグメンテーションが起きている。フラグメントが一つ失われるだけでパケット全体が失われ、フラグメントを最初から破棄するNAT・ファイアウォールもある。途中でMTUの小さい区間(トンネル・VPN)を通るユーザーでは、大きなパケットだけが消える。ppsが増えたなら、クラウドインスタンスのPPS上限や、ファイアウォール・DDoS対策機器の処理上限に達していないかを確認する。最初に呼ぶ担当:フィンガープリントが変わっていれば証拠を添えてゲーム開発チーム(サーバー)、変わっていないのにパケットロス・再送だけ増えたならインフラチーム(ネットワーク)。 (アップデートによるトラフィックパターンの変化 , UDPパケットのIPフラグメンテーション , MTUブラックホール(大きいパケットだけ繰り返し失われる) , クラウドのPPS上限超過 , 中間機器の処理上限超過(ファイアウォール・IPS・DDoS対策) , 送信バーストによる浅いバッファのあふれ ) DBクエリの種類と回数を前後で比較する : DBの遅延が増えたなら、まずクエリ数(QPS)も一緒に増えたかを確認する。PostgreSQLのpg_stat_statementsやMySQL Performance Schemaのdigestサマリーは、値だけが異なるクエリをひとまとめにして実行回数と合計時間を集計してくれる。アップデート前後の上位クエリ一覧を比較すれば、新たに現れたクエリ、回数が数倍に増えたクエリ(N+1)、インデックスを使わずにテーブル全体を読むクエリ(MySQLではSUM_NO_INDEX_USEDカラム)が浮かび上がる。最初に呼ぶ担当:QPSやクエリの形が変わっていればゲーム開発チーム(サーバー)、クエリは同じで遅延だけ増えたならインフラチーム(DB:実行計画・IOPS・ロック)。 (インデックスのないクエリ , ログイン殺到とN+1クエリ , 実行計画の変化によるクエリ遅延 , キャッシュスタンピード ) ホストとサーバープロセスのメトリクスで階層を切り分ける : コードに頼らず、OSから見える値でサーバープロセスの内側とホストを切り分ける。サーバーソケットの受信キュー(Recv-Q)がたまっていれば、サーバープロセスが時間どおりに読み出せていない(ティックの停止・GC・ロック)。一つのスレッドだけが100%ならシングルスレッドのボトルネック、GCログの停止時間が延びていればメモリの使い方が変わったということだ。ログレベルを上げたままデプロイしてログ書き込みが増えていないかも確認する。逆に、CPUスチール・スロットリング・NICのドロップが増えていれば、同じ時刻に変わったインフラ(インスタンスタイプ・カーネル・コンテナの上限)を確認する。最初に呼ぶ担当:プロセス内側のシグナルならゲーム開発チーム(サーバー)、ホストのシグナルならインフラチーム(サーバー機器・OS)。 (サーバーGCの全停止 , シングルスレッドのエリア過負荷(ホットスポット) , 同期ログ書き込み , コンテナのCPUスロットリング(CFSクォータ) , CPUスチール(仮想マシン) , OS・カーネル・ドライバー・ファームウェアのアップデート後の性能変化 ) 元に戻して確定し、記録を残す : 最も有力な変更を一部のサーバーや一部のユーザーに対してだけ元に戻す(ロールバック、フィーチャーフラグをオフ)か、設定を以前の値に戻し、症状も一緒に消えるかを確認する。戻した側だけが改善すれば原因が確定する。戻す作業でも再起動とコールドキャッシュで一時的に重くなることがあるので、急ぎでなければ空いている時間帯に行う。結果は原因IDとともに障害記録に残し、パケットサイズ・クエリ数・ティック時間の上限を、次のアップデートのデプロイ前チェック項目に加える。最初に呼ぶ担当:変更を入れたチーム。 (デプロイ・再起動 , コールドキャッシュ(再起動直後) )
海外の国・地域の追加 サービス提供国を新たに開くとき、または新しいリージョン・データセンターを追加するとき。オープン前の点検と、「国内は問題ないのに新しい国のユーザーだけラグい」という報告の切り分けの両方に使う。
現地の通信事業者ごとの経路品質をオープン前に測る : 対象国の主要な通信事業者(ASN)ごとに、ゲームサーバーの候補地までの往復時間(RTT)の分布、ジッター、パケットロスを測る。平均値一つでは通信事業者ごとの差が埋もれるので、通信事業者別の中央値と95パーセンタイルを、夜のピークと深夜に分けて確認する。公開測定網のRIPE Atlasでは、国・ASNを指定して世界中のプローブからping・tracerouteを送れる。候補リージョンに一時的なVMを立てて測ってもよい。途中の機器がICMP応答をレート制限することもあるので、可能ならゲームと同じプロトコル・ポートでも測る。特定の通信事業者だけが際立って遠い都市を経由していれば、ピアリング・経路の問題だ。通信事業者は遅延よりもコストの低い経路を選ぶため、近い場所でも遠回りすることがある。最初に呼ぶ担当:インフラチーム(ネットワーク)、経路が通信事業者側の問題なら外部(通信事業者・IX)。 (伝搬遅延(物理的な距離) , 迂回ルーティング , ピーク時間帯のピアリング混雑 , 海底ケーブル・国際回線の障害 ) 測定値を、ゲーム設計が耐えられる上限と比較する : 測ったRTT・ジッターを、ゲームの判定の受付時間(回避・パリィなどの反応時間)、ラグコンペンセーションの上限、補間バッファの長さ、入力バッファのサイズと比較する。たとえばパリィの判定が0.2秒なら、往復遅延と補間バッファを足した値がそれより長い通信事業者のユーザーは、タイミングどおりに反応しても間に合わない。ラグコンペンセーションを広げて合わせると、今度は攻撃を受ける側から「壁の裏にいたのに当たった」という報告が増える。上限を超える通信事業者が多ければ、インフラチームはリージョン・エッジPoPをより近くに置く案を、ゲーム開発チームは判定・補間・ラグコンペンセーションの値を検討する。白書の「同期方式」の章が基準表になる。最初に呼ぶ担当:ゲーム開発チーム(サーバー・クライアント:設計上の上限)、インフラチーム(ネットワーク:リージョン・PoPの位置)。 (Pingに削られる短い判定の受付時間 , ラグコンペンセーションのない判定 , 過剰なラグコンペンセーション , 補間バッファがないか短い ) MTUとUDPが通るかを確認する : 現地のネットワークで、ゲームの最大パケットが欠けずに通るかを確認する。フラグメント化禁止(DF)フラグを立てたpingをサイズを変えながら送って経路MTUを測り、PPPoE・トンネル・モバイル回線のように1,500バイトより小さい区間がないかを確認する。UDPのようなデータグラム転送の標準(RFC 8899)は、IPv4でほとんどの経路を通過できる基本サイズとして1,200バイトを推奨している。ゲームの最大パケットがこれより大きければ、小さくするか分割して送る方法をゲーム開発チームと決める。公衆Wi-Fi・社内ネットワーク・一部の通信事業者でUDPやゲームのポートがブロックされたり速度制限されたりしないかも確認し、ブロックされたときの代替経路(TCP・443番ポート)があるかを確認する。最初に呼ぶ担当:インフラチーム(ネットワーク)とゲーム開発チーム(サーバー:パケットサイズ)。 (MTUの不一致(大きなパケットだけ消える) , MTUブラックホール(大きいパケットだけ繰り返し失われる) , UDPパケットのIPフラグメンテーション , 国・通信事業者単位のUDP制限・パケット検査 , 公衆Wi-Fi・社内ネットワークの制限 , 通信事業者の速度制限・トラフィック管理 ) NAT・CGNATのアイドルタイムアウトを測り、ハートビート間隔を合わせる : 現地の家庭用ルーターとモバイル回線(CGNAT)が、アイドル状態のUDP接続のマッピングをどれくらいで消すかを測る。試験ごとに、テスト端末からサーバーへパケットを一つ送ってマッピングを作り、その後は端末から何も送らず、決めておいた時間(30秒、60秒、120秒…)が過ぎてからサーバーが端末へパケットを送るようにする。端末がそのパケットを受け取れなくなり始める時間が、そのネットワークのアイドルタイムアウトだ。標準(RFC 4787)は、UDPマッピングを2分未満で期限切れにしてはならず、デフォルトは5分以上を推奨しているが、機器によって値は大きく異なり、もっと短く消す機器もある。マッピングが確実に更新されるのは端末から出ていくパケットだけなので、ハートビートはクライアントから送る。その間隔が、測った値とロードバランサー・クラウドのセキュリティグループのアイドルタイムアウトのうち最も短い値の半分以下になっているかを確認する。最初に呼ぶ担当:ゲーム開発チーム(クライアント:ハートビート間隔、サーバー:タイムアウト値)、インフラチーム(ロードバランサー・セキュリティグループの設定)。 (NATマッピングの期限切れ , 通信事業者の共有IP(CGNAT) , 接続中のNAT・ロードバランサーのマッピング期限切れ , ロードバランサーのアイドルタイムアウト , クラウドのセキュリティグループによる接続追跡の期限切れ ) 現地で経由する外部サービスとセキュリティ機器を確認する : 現地のプラットフォームのログイン・決済・本人認証が本来の速さで応答するか、現地のDNSでログインサーバー・アップデートサーバーのアドレスが正しく解決されるか、CDNがその国に近い拠点からアップデートデータを配信しているかを確認する。DDoS対策・ファイアウォールの国別ブロックルールやレート制限に新しい国のIPアドレス帯が引っかからないかを確認し、特に複数の加入者が一つのIPを共有するCGNATのアドレス帯がまとめてブロックされないかを確認する。最初に呼ぶ担当:インフラチーム(セキュリティ機器・DNS・CDN)、外部(プラットフォーム・決済事業者・通信事業者)。 (外部サービスへの依存 , DNSの障害・遅延 , DDoS対策の経由・誤検知 , 通信事業者の共有IP(CGNAT) ) オープン後は国・ASN別に分けて確認する : 接続ログ・ロードバランサーログのクライアントIPに国とASNを付与し、国・通信事業者別にRTT、再送、切断の回数と理由(ハートビートタイムアウト・RST・サーバーからのキック)を確認する。MaxMind GeoLite ASNのような無料データベースでIPをASNと組織名に変換できる。現地の個人情報保護規制に合わせて、IPは/24やASN単位に丸めて保管する。一つのASNだけに集中していればその通信事業者の経路(インフラチーム・外部)、新しい国全体が悪ければ距離と設計上の上限(インフラチーム・ゲーム開発チーム)、夜だけ悪化するならピアリングの輻輳を、まず疑う。一部のユーザーだけ常にPingが高ければ、GeoIPの誤り・VPN・パーティリーダー基準の割り当てによって遠いリージョンに割り当てられていないかを、ゲーム開発チーム(サーバー)と一緒に確認する。外形監視は正常なのにユーザーだけが悪ければ、ユーザー環境かクライアント側の問題だ。 (ピーク時間帯のピアリング混雑 , 迂回ルーティング , ボトルネックでのキューあふれ(輻輳によるロス) , 特定の通信事業者のユーザーに集中する検証の誤検知 , マッチメイキング・リージョン割り当ての誤り ) 遠い地域のユーザーがほかのユーザーに与える影響を確認する : 遠くから接続するユーザーが増えると、その人の画面が悪くなるだけでは済まない。遅延の大きい人の入力がまとめて届くため、ほかの人の画面ではそのキャラクターだけが早送りで動き、サーバーの速度・クールタイムのチェックに引っかかって引き戻しやスキルの拒否が起きる。パーティギミックでは、遅延の大きい一人の反応の遅れがパーティ全体の失敗につながり、ロックステップ方式では最も遅い人を全員が待つ。新しい国のオープン後に既存ユーザーからの「特定のキャラだけおかしく見える」という報告が増えていないかを確認し、入力バッファ・検証の許容値・マッチング地域の分離をゲーム開発チームと決める。最初に呼ぶ担当:ゲーム開発チーム(サーバー)。 (回線が重い人がほかの人の画面でまとめて動く , 特定の通信事業者のユーザーに集中する検証の誤検知 , 回線が重いパーティメンバー1人とボスのギミック , ロックステップでの最も遅いプレイヤー待ち )
実際の障害事例
ゲーム会社とインフラ企業が自ら公開したポストモーテムだけを選びました。
CCP Games 2014: EVE OnlineのHED-GP大規模艦隊戦でのサーバー過負荷 何が起きたか 2014年1月のポストモーテムで取り上げられたHED-GP星系の大規模艦隊戦で、サーバーが深刻な過負荷に陥った。Time Dilation(過負荷時にゲーム内の時間の進みを遅くする機能)が下限の10%に達し、戦場全体がスローモーションになった後も負荷はたまり続けた。モジュールの停止や繰り返し作動を処理する作業の遅れ(Dogma Lateness)は、最大でゲーム内時間193秒、実時間で約32分に達した。規模がほぼ同じだった2013年7月の6VDTの戦闘では、最大42秒(実時間で約7分)だった。 原因 CCPは、性能分析ツール自体が負荷を増やすためこうした状況では動かしておらず、確実なことは言えないと前置きしたうえで、2つを有力な原因に挙げた。1つは、戦闘が長引くにつれて処理しきれない負荷がたまり続けたことだ。もう1つはドローンの使用増加で、戦闘中に展開されたドローンの数(重複を除く)は6VDTが21,123機、HED-GPが38,852機と84%多かった。一人の行動を、それが見える全員に知らせる送信は人数の二乗(O(n²))で増えるが、ドローンは1回の攻撃で発生するメッセージがさらに多い。ドローンが攻撃対象を選ぶコードも、同じ戦場で攻撃可能な対象を頻繁に総当たりで調べるため、コストがn²に近い形で増える。 教訓 人が集中した一つのエリアの処理量が限界を超えると、そのエリア全体がスローモーションになり、戦闘が長引くほど処理の遅れがたまって入力遅延が大きくなる。確認すべきシグナルは、そのエリアを担当するサーバー(ノード)のティック時間・滞留した作業量と、人数・オブジェクト数だ。ほかのエリアは正常なのが特徴だ。主担当はゲーム開発チーム(サーバー)で、一つの行動を通知する相手の範囲と、AIの対象探索コストが改修ポイントになる。ゲーム内の時間を遅くする設計で過負荷そのものはなくせないが、全員が同じ速さで遅くなるので、一部の行動だけが際限なく後回しになることを防げる。 関連する原因 ブロードキャストの急増 , ティックバジェット超過 , メッセージキューの滞留 , シングルスレッドのエリア過負荷(ホットスポット) 原文 CCP Games
Riot Games 2015: 遠回りしていたLeague of LegendsのトラフィックとRiot Direct 何が起きたか Riot Gamesが、インターネットがリアルタイムゲームに向いていない理由を解説した技術記事だ。League of Legendsのユーザーが報告した実際のトラフィックは、サンフランシスコからポートランドへまっすぐ向かうべきところをロサンゼルス、デンバー、シアトルを経由しており、直行なら14msで済むところが70msかかっていた。Riotは、ルーターがあふれてパケットが破棄されると、ほかのチャンピオンが画面上で飛び跳ねるように動き、投射物がワープしたように見えると説明した。 原因 Riotは経路とルーターを原因に挙げた。バックボーン事業者と通信事業者は、遅延が最も短い経路よりもコストが最も安い経路でトラフィックを流し、BGPで決まった経路が遠回りになれば経由するルーターの数も増える。ルーターの処理負荷は、パケットのサイズに関係なく個数に比例する。ゲームのパケットは55バイト前後なので、同じデータ量なら1,500バイトのパケットより個数が27倍になり、その分ルーターの入力バッファを早く埋める。Riotの説明によれば、過負荷になるとUDPパケットから先に破棄するルーターも多い。解決策としてRiotは、米国の主要なインターネット拠点10か所にルーターを置き、できるだけ多くの通信事業者と直接接続(ピアリング)する自社ネットワークRiot Directを構築した。第2部によると、Pingが80ms未満でプレイするユーザーの割合は9か月あまりで31%から50%に上がり、ゲームサーバーをシカゴに移すと一晩で80%になった。 教訓 同じ国の中でも特定の通信事業者のユーザーだけPingが際立って高ければ、経路を疑う。確認すべきシグナルは、通信事業者(ASN)別のRTT分布と、tracerouteに表れる経由都市だ。主担当はインフラチーム(ネットワーク)で、通信事業者との直接ピアリング、IX接続、サーバーの設置場所の選定で解決する。通信事業者側の経路ポリシーは、外部(通信事業者)と協議する事項だ。サーバーをユーザー分布の中心近くに移すだけでも効果が大きいことも、この事例は示している。 関連する原因 迂回ルーティング , 伝搬遅延(物理的な距離) , ボトルネックでのキューあふれ(輻輳によるロス) 原文 Riot Games
Riot Games 2020: League of Legendsの欧州・ブラジルサーバーでのエッジホスト過負荷 何が起きたか 2020年2月末、League of LegendsのEUW・EUNE・BRサーバーで障害が何度も発生し、新たに始まるゲームの数が大きく減った。マッチング・ゲームサーバーなどのバックエンドサービスはどれも正常な状態だったが、流入するトラフィックがほとんどなかった。Riotは、不安定になりうるクラスターでトーナメントモード(Clash)を開催しないよう、日程を1週間延期した。ポストモーテムには、障害ごとの継続時間は書かれていない。 原因 3つの要素が重なった。あるサービスへのリクエストが誤った形で組み立てられており、特定の条件で失敗と再試行を繰り返したため、リクエストが急増した。コンテナシステムとOSバージョンの既知の相性問題でOS内部のメモリがリークしていたが、アップグレードはRiotのコンテナ環境全体の約60%でしか終わっておらず、欧州・ラテンアメリカのクラスターは作業中だった。インターネットからのトラフィックを受けてフィルタリングし、バックエンドへ渡すエッジコンテナは、同じシャード(サーバー群)の中では別々のホストに配置されていたが、異なるシャード同士が同じホストに載るのは防げていなかった。そのため障害のたびに、少なくとも3つのシャードのエッジコンテナが1台のホストに集中していた。再試行の急増がそのホストに重なり、メモリリークがそのホストを停止させた。 教訓 バックエンドのサービスがどれも「正常だがトラフィックが来ない」という状態なら、その手前(エッジ・ゲートウェイ・ロードバランサー)を確認する。確認すべきシグナルは、ホスト別のインバウンド接続数の偏りと、特定リクエストの失敗・再試行の比率だ。主担当はゲーム開発チーム(サーバー:誤ったリクエストと再試行の方式)で、コンテナの配置ルール・OSのアップグレード・偏りのアラートはインフラチーム(サーバー機器・OS)が受け持つ。Riotはリクエストのコードを修正して再試行が急増しないように変え、シャード間の分散配置を実装するまでの間、偏りを検知するアラートを設けた。 関連する原因 ゲートウェイ・プロキシ経由 , カスケード障害 原文 Riot Games
Riot Games 2021: League of Legends EUWの5時間障害:補助的なDB一つでサーバー全体が停止 何が起きたか 2021年1月22日、League of LegendsのEUWサーバーが5時間強にわたって正常に動作しなかった。ログイン中のユーザー数とゲーム中のユーザー数のメトリクスが一斉に途切れ、2回の再起動の間は、ログインは増えてもゲームはほとんど始まらなかった。 原因 重要度の低い機能を担うDBのプライマリサーバーでハードウェア故障が起き、そのDBには予備サーバーへの自動フェイルオーバーが設定されていなかった。コネクションプールはDBごとに分かれていたが、すべてのプールが同じスレッドプールを使っており、故障したDBに送った処理が終わらないままスレッドを占有したため、システム全体で使えるスレッドが枯渇した。大量のアラートが鳴る中、最近受けた悪意あるネットワーク攻撃や別リージョンでのハードウェア作業を先に疑ったため、故障したDBのアラートに気づいたのは約1時間後だった。すべてのシステムが1つのJVMで動く構成だったため、再起動後の再接続の負荷の中でGCがプロセスを数秒ずつ止めると、メトリクス収集にも大きな空白が生じた。ログイン待機列も設定した上限を守らず、流入が安定しなかった。 教訓 重要ではないと考えていた補助的なDB一つでも、スレッドプールのような共有リソースを通じて全体を止めうる。確認すべきシグナルは、DB別の待機中リクエスト数とスレッドプール使用率、そしてログイン数に対してゲーム開始数が少なすぎる比率だ。担当はゲーム開発チーム(サーバー:スレッドプールの分離・タイムアウト)とインフラチーム(DB:自動フェイルオーバー)だ。アラートが大量に出ているときは最近経験した問題(攻撃など)から疑いがちなので、切り分けの順序(範囲 → 時点 → 階層)に沿って一つずつ除外する。再起動後は、ログイン待機列が設定どおりに流入を制限しているかもあわせて確認する。 関連する原因 スレッドプールの枯渇 , DBのフェイルオーバー , カスケード障害 , サーバーGCの全停止 原文 Riot Games
Roblox 2021: Robloxの73時間障害:サービスディスカバリ(Consul)クラスターでの競合 何が起きたか 2021年10月28日午後(太平洋時間)、Consulサーバー1台の高いCPU負荷から始まり、16時35分に接続中のユーザー数が普段の半分に落ちた後、サービス全体が停止した。すべてのユーザーが再び入れるようになったのは10月31日16時45分で、障害発生から73時間かかった。Robloxは、毎日5千万人が利用していると公表している。 原因 Robloxはサービスディスカバリ(サービス同士が互いのアドレスを見つける仕組み)、ヘルスチェック、KVストアにHashiCorp Consulを使っており、1つのConsulクラスターが複数のワークロードをまとめて担っていた。根本原因は2つあった。1つ目は、数か月かけて適用範囲を広げてきたConsulの新しいstreaming機能を、障害の前日にトラフィックルーティングサービスでも有効にし、そのサービスのノード数を50%増やしたことだ。読み込みと書き込みがどちらも非常に多い負荷のもとで、この機能は1つの共有リソース(Goのチャネル)での競合を引き起こした。障害中に入れ替えた、コア数がより多いデュアルソケット(NUMA)サーバーでは、競合がさらに激しくなった。2つ目は、ConsulがRaftログの保存に使うBoltDBで空きページリスト(freelist)の管理が異常に遅くなり、16kB以下のデータを追加するたびに7.8MBをディスクに書き込んでいたことだ。普段は300ms未満だったKV書き込みレイテンシの中央値は2秒になり、遅いリーダーサーバーではTCPバッファが満杯になるゼロウィンドウも観測された。テレメトリもConsulに依存していたため、原因調査に必要なメトリクスまで一緒に失われた。 教訓 複数のサービスが共通して依存する基盤システム(サービスディスカバリ・設定ストア・認証)が遅くなると、すべての機能が一斉に止まる。確認すべきシグナルは、そのシステムの書き込みレイテンシ・リーダー交代・CPUと、障害直前の設定変更だ。担当はゲーム開発チーム(サーバー)とインフラチーム(サーバー機器・OS)の両方だ。障害時にもメトリクスを確認できるよう、監視は監視対象のシステムに依存しない形で分離しておく。復旧時はキャッシュが空で、一気に受け入れると再び崩れるおそれがあるため、RobloxはDNSで入場できるユーザーの割合を調整しながら約10%ずつ増やした。 関連する原因 カスケード障害 , ロック競合 , ゼロウィンドウ(再送のように見える停止) , コールドキャッシュ(再起動直後) 原文 Roblox
Square Enix 2021: FINAL FANTASY XIVの拡張パッケージ発売時の混雑とログイン待機列のエラー 何が起きたか 2021年12月、拡張パッケージ『暁月のフィナーレ』(Endwalker)のアーリーアクセス開始から、各ワールドが極度に混雑した。ログイン待機列が長くなり、キャラクター選択画面からログインするときや待機列で待っている間にエラー2002が頻発した。一部のワールド・ゾーンのダウン(エラー3001)や待機列のタイムアウト(エラー4004)も起きた。12月11日のお知らせの時点でも、アーリーアクセス8日目で混雑が続いていた。 原因 エラー2002は2つのケースで発生する。1つは、論理データセンターごとの待機人数が17,000人を超えたときだ。待機列が長くなりすぎてログインサーバーがダウンするのを防ぐための上限で、このときはクライアントが完全に終了する。12月7日に開発用の予備機材をロビーサーバーに投入して上限を引き上げると、このエラーは減ったものの、待機列はかえって長くなった。もう1つは、待機中のユーザーの回線が不安定なときだ。待ち時間が長くなるにつれ、インターネット経路のパケットロスやWi-Fiの不安定さで接続が一瞬切れることが増えた。ロビーサーバーは数十秒から1分ほど再接続を待ち、その間に再接続できれば待機列の途中から再開できるが、それを過ぎると最後尾に並び直しになる。スクウェア・エニックスは、報告の大半がこのケースだとしている。半導体不足のため、ワールドをすぐに増やすこともできなかった。 教訓 待機列が長くなるほど、待機中のユーザー回線で起きる瞬断が接続エラーに変わる。同じ混雑の中でも、Wi-Fiや不安定な回線を使う人にエラーが集中する「一部のユーザーだけに起きる問題」になる。確認すべきシグナルは、待機列の長さ・待ち時間と、切断理由のうち待機中の切断が占める割合だ。主担当はゲーム開発チーム(サーバー:待機列の上限と再接続の猶予時間)で、ロビー・ワールドサーバーの増設はインフラチームが一緒に行う。再接続の猶予時間を十分に取れば、ユーザー回線の瞬断が待機順を失う事態に発展するのを減らせる。 関連する原因 ログイン待機列の上限・再接続猶予の不足 , Wi-Fiの干渉・電波の弱さ , 無線区間のパケットロス 原文 Square Enix
Cloudflare 2020: Cloudflareのバックボーン設定ミスで一部都市のトラフィックが途絶 何が起きたか 多くのゲームがWeb・API・DDoS対策をCDN事業者に任せているため、ゲームも巻き込まれるタイプのインフラ障害だ。2020年7月17日21:12から21:39(UTC)までの27分間、Cloudflareネットワーク全体のトラフィックが約50%減少した。影響はバックボーンに接続された米国・欧州・ロシア・ブラジルの一部都市の拠点に限られ、ほかの拠点は正常だった。 原因 ニューアークとシカゴを結ぶバックボーン区間の障害でアトランタとワシントンを結ぶ区間が輻輳したため、エンジニアがアトランタのバックボーントラフィックを減らそうとルーターの設定を変更した。ポリシーの項目(term)全体を無効にすべきところ、その中の条件(prefix-list)だけを無効にしたため、アトランタのルーターがすべてのBGP経路をより高い優先度(local-preference 200)でバックボーン全体に広報した。各拠点が自拠点のサーバーへの経路に設定していた優先度は100だったため、バックボーンに接続された拠点のトラフィックがすべてアトランタに集中した。アトランタは過負荷になり、影響を受けた拠点では処理するトラフィックがほとんどなくなった。アトランタのルーターをバックボーンから外すと復旧した。Cloudflareは、攻撃や侵害とは関係がないと説明した。 教訓 特定の都市・地域のユーザーだけが一斉に切断されたり接続不可・無限ロードになったりして、ほかは正常なら、直前の経路設定の変更をまず疑う。グラフでは一つの拠点だけCPU・トラフィックが急上昇し、影響を受けた拠点はむしろ0近くまで落ちる。主担当はインフラチーム(ネットワーク)で、事業者側の障害なら外部だ。Cloudflareは、バックボーンのBGPセッションに受信できる経路数の上限(maximum-prefix)を設けることにし、ある拠点がほかの拠点のトラフィックを引き寄せられないよう優先度を調整した。 関連する原因 BGPの経路変更・収束 , 経路変更・ECMPの不良経路 原文 Cloudflare
Fastly 2021: Fastly CDNで世界規模のエラー 何が起きたか 多くのゲームがアップデートファイル・ランチャー・WebページをCDNで配信しているため、ゲームも巻き込まれるタイプのインフラ障害だ。2021年6月8日09:47(UTC)から、Fastlyネットワークの85%がエラーを返した。49分以内にネットワークの95%が正常に戻り、12:35に障害は収束した。 原因 5月12日に始まったソフトウェアのデプロイに、特定の顧客設定が特定の条件を満たしたときに発動するバグが含まれていた。6月8日、ある顧客が正当な設定変更を反映したことで、その条件がそろった。Fastlyは1分で異常を検知し、原因となった顧客設定を特定して無効にすると復旧が始まった。バグ修正のデプロイは同日17:25に開始した。 教訓 デプロイから数週間たったコードでも、まれな条件に当たると一瞬で世界規模の障害になる。ゲーム側で確認すべきシグナルは、アップデート・ランチャー・WebリクエストのHTTPエラー率がすべての地域で同時に上がることと、CDN事業者のステータスページだ。接続済みのゲーム通信はCDNを経由していなければ正常で、新規接続・アップデートのダウンロード・Webログインだけが止まるのが特徴だ。主担当は外部(CDN事業者)で、ゲーム開発チーム・インフラチームは、CDNを複数使うか、オリジンサーバーから直接取得する迂回経路を用意しておく。 関連する原因 外部サービスへの依存 原文 Fastly
Meta 2021: バックボーンへのコマンド一つでDNSまで消えたFacebookの障害 何が起きたか ゲーム会社の自社ネットワークとDNSにもそのまま当てはまるインフラ障害だ。2021年10月4日、Facebook(現Meta)のサービスに世界中で接続できなくなった。データセンター間をつなぐバックボーンがすべて切れ、インターネット側からFacebookのDNSサーバーを見つけられなくなった。ポストモーテムには、障害の継続時間は書かれていない。 原因 定期メンテナンス作業中、世界全体のバックボーン容量を確認するために実行したコマンドが意図に反してバックボーンのすべての接続を切断し、こうしたコマンドを止めるはずの監査ツールはバグのため止められなかった。小規模拠点のDNSサーバーは、データセンターと通信できないと自らを異常と判断してBGP広報を取り下げる仕組みだったため、DNSサーバーは動いているのにインターネットから到達できなくなった。通常のアクセス経路も帯域外(out-of-band)アクセスもすべて断たれ、内部ツールもDNSを失ったため、エンジニアをデータセンターへ直接派遣する必要があり、セキュリティ手順のためにさらに時間がかかった。復旧時は、データセンターごとに電力使用量が数十MWずつ落ちていたため、一気に戻すと電力設備からキャッシュまで危険にさらされうると判断し、負荷を段階的に上げた。 教訓 すべての地域・すべての通信事業者で同時に接続不可・無限ロードが起きたら、ゲームサーバーよりも先にDNSとBGP経路を確認する。外部からのDNS問い合わせと公開されているBGP経路情報を使えば、社外からでも確認できる。主担当はインフラチーム(ネットワーク)だ。障害時に使う帯域外アクセス経路や内部ツールが同じDNS・ネットワークに依存していないかを事前に点検し、復旧時は再接続が一気に集中しないよう負荷を段階的に上げる。 関連する原因 BGPの経路変更・収束 , DNSの障害・遅延 原文 Meta
AWS 2021: AWS us-east-1の内部ネットワーク輻輳 何が起きたか 多くのゲームがサーバー・ログイン・データをパブリッククラウドに置いているため、ゲームも巻き込まれるタイプのインフラ障害だ。2021年12月7日午前7時30分(太平洋標準時)、北バージニアリージョン(us-east-1)の内部ネットワークが輻輳した。7時33分からEC2 APIのエラーと遅延が増えて新しいインスタンスを起動しにくくなり(インスタンスの起動は午後2時40分に回復)、コンソールへのログイン失敗、Route 53の設定変更不可、CloudWatchメトリクスの遅延と一部欠損が続いた。ネットワーク機器は午後2時22分に完全に回復した。すでに稼働していたEC2インスタンスと既存のDNS応答は影響を受けなかった。 原因 メインネットワーク上のあるサービスの容量を増やす自動処理が、内部ネットワークの多数のクライアントで予期しない動作を引き起こし、接続試行が急増した。内部ネットワークとメインネットワークをつなぐ機器があふれて通信が遅延し、その遅延がさらに接続試行と再試行を増やして輻輳が続いた。クライアントにはこうした輻輳時にリクエスト間隔を広げるバックオフの仕組みがあったが、潜在的な不具合のため正しく動作しなかった。内部の監視も同じネットワークに依存していたため、運用チームはリアルタイムのメトリクスなしにログを頼りに対応した。 教訓 再試行の間隔を広げられないと、短い輻輳が数時間の障害になる。ゲーム側から見ると、稼働中のゲームサーバーは正常でも、新しいサーバーの増設(オートスケーリング)、クラウドAPIを使うログイン・マッチング・決済、監視がまとめて止まることがある。確認すべきシグナルは、クラウド事業者のステータスページ、クラウドAPIのエラー率、インスタンスの起動失敗だ。主担当は外部(クラウド事業者)だ。ゲーム開発チームはすべての再試行にランダムな間隔の指数バックオフと回数制限を設け、インフラチームは増設できなくても持ちこたえられる余剰容量と、別リージョンという代替手段を用意する。 関連する原因 カスケード障害 , オートスケーリングの遅れ , 外部サービスへの依存 原文 AWS
Cloudflare 2025: CloudflareのパブリックDNS 1.1.1.1の障害 何が起きたか ユーザーが端末やルーターに自分で設定して使うパブリックDNSリゾルバーの障害で、その設定を使うユーザーに限って、すべてのゲームとサービスがまとめて使えなくなるタイプだ。2025年7月14日21:52から22:54(UTC)までの62分間、1.1.1.1リゾルバーが世界中で応答しなかった。Cloudflareは、多くの利用者にとってこれは事実上すべてのインターネットサービスが使えないことを意味したと述べている。UDP・TCP・DNS over TLSによる問い合わせが影響を受け、ドメイン名で接続するDNS over HTTPSは比較的安定していた。 原因 6月6日、今後使う予定の別サービスのサービストポロジー(どの拠点からIPアドレス帯を広報するかを定めた構成)を準備する際、1.1.1.1リゾルバーのIPアドレス帯が誤ってその構成に含められた。7月14日にそのサービスの構成を変更すると、リゾルバーのアドレス帯を広報する拠点が全拠点からオフラインの1か所に減り、世界中でBGP経路が取り下げられた。この変更はカナリアリリースを経ずに、すべてのデータセンターへ即座に反映された。22:20に設定を戻すとトラフィックは約77%まで回復したが、その間にエッジサーバーの約23%で必要なIP設定が消えていたため再設定が必要になり、正常に戻ったのは22:54だった。Cloudflareは、攻撃やBGPハイジャックとは関係のない内部の設定ミスだと説明した。 教訓 ゲームサーバーもほかのユーザーも正常なのに、一部のユーザーだけがログインサーバーやアップデートサーバーに接続不可・無限ロードになるなら、そのユーザーが使っているDNSを疑う。接続済みのセッションは維持され、新規接続だけが失敗するのが特徴だ。ユーザーにDNS設定を変えてもらうか、サーバーのアドレスを直接問い合わせてもらえば、すぐに見分けがつく。主担当は外部(DNS運営者・通信事業者)だ。ゲーム開発チーム(クライアント)が名前解決の失敗をほかのエラーと区別して表示すれば、カスタマーサポートがその場で切り分けられる。 関連する原因 DNSの障害・遅延 , BGPの経路変更・収束 原文 Cloudflare
AWS 2025: AWS us-east-1のDynamoDB DNS障害と長引いた復旧 何が起きたか 多くのゲームがサーバー・ログイン・データをパブリッククラウドに置いているため、ゲームも巻き込まれるタイプのインフラ障害だ。2025年10月19日午後11時48分から20日午後2時20分(太平洋夏時間)まで、北バージニアリージョンで3段階にわたって影響が続いた。20日午前2時40分まではDynamoDB APIのエラーが増え、午前2時25分から10時36分までは新しいEC2インスタンスの起動が失敗し(一部の新しいインスタンスの接続問題は午後1時50分に解消)、午前5時30分から午後2時9分までは一部のNetwork Load Balancer(NLB)で接続エラーが増えた。 原因 DynamoDBのDNSを管理する自動化の仕組みに、潜在的な競合状態(race condition)があった。異なるアベイラビリティーゾーンでDNSプランを適用する実行コンポーネント(DNS Enactor)のうち、異常に遅れていた1つが古いプランで新しいプランを上書きした直後に、別の実行コンポーネントのクリーンアップ処理がその古いプランを削除し、リージョンエンドポイント(dynamodb.us-east-1.amazonaws.com)のDNSレコードが空になった。自動化の仕組みではこれを修復できず、人手で復旧する必要があった。EC2の物理サーバー管理システムはDynamoDBに依存していたため、その間に物理サーバーごとに維持していたリース(lease)が期限切れになった。DynamoDBが復旧した後は、物理サーバーの数が多すぎてリースを結び直す処理が終わる前にタイムアウトし、再試行の処理が再びたまって「輻輳崩壊(congestive collapse)」の状態に陥った。新たに起動したインスタンスのネットワーク設定の反映が遅れたため、NLBのヘルスチェックが成功と失敗を行き来し、正常なノードまでDNSから外れては戻ることを繰り返した。 教訓 一か所のDNSレコードの誤りが、そのサービスに依存する別のサービスへ波及し、原因が解消した後も、滞留した処理とヘルスチェックの不安定さのせいで復旧にさらに数時間かかる。ゲーム側から見ると、稼働中のサーバーは持ちこたえても新しいサーバーを起動できずにオートスケーリングが止まり、ヘルスチェックが不安定になるとロードバランサーが正常なサーバーを外してしまうことがある。確認すべきシグナルは、クラウドのステータスページ、マネージドサービスのAPIエラー率、インスタンスの起動失敗、ロードバランサーの正常なターゲット数だ。主担当は外部(クラウド事業者)で、インフラチームはヘルスチェックの失敗で一斉に外れるサーバー数を制限し、別リージョンという代替手段を用意する。 関連する原因 外部サービスへの依存 , カスケード障害 , オートスケーリングの遅れ , ロードバランサーの偏り・ヘルスチェックの誤判定 , DNSの障害・遅延 原文 AWS
用語集
Ping Ping, RTT. 自分が送った信号がサーバーまで行って戻ってくるまでの時間(往復)。ゲームに表示されるPingには、サーバーの処理待ち時間が含まれていることもあります。
遅延 Latency. パケットが送り出されてから到着するまでの時間。片道を指すことが多く、Pingのおよそ半分です。
ジッター Jitter. 到着間隔のばらつき。平均Pingが同じでも、ジッターが大きいと画面がカクつきます。
パケット Packet. ネットワークで一度に送るデータのまとまり。通常は最大1,500バイトで、ゲームの更新データは数十〜数百バイトです。
パケットロス Packet loss. 送ったパケットが届かずに消えること。TCPを使うゲームでは1%でも数秒〜十数秒に一度カクッと止まるのが感じられ、補間や入力の重複送信を備えたUDPのゲームなら数%まで隠せることもあります。
帯域幅 Bandwidth. 回線が1秒間に送れる最大データ量(Mbps)。どれだけ早く届くか(遅延)とは別の概念です。
ティック Tick. サーバーがゲーム状態を一度計算する単位。20ティックのサーバーは1秒に20回、50msごとに計算します。
ティックレート Tick rate. 1秒間にティックを何回回すか。高いほど反応が速くなりますが、サーバーコストと通信量が増えます。通信量を抑えるため、パケットを送る回数はティックレートより低く設定することもあります。
ティックバジェット Tick budget. 1ティックを終えなければならない時間の上限。超えると次のティックが遅れ、ティック間隔が延びます。
FPS Frames per second. 1秒間に画面を何回描画するか。60FPSなら1フレームあたり16.7ms。
フレームタイム Frame time. 1フレームの描画にかかった時間。平均FPSよりも、ときどき跳ねるフレームのほうが体感には重要です。
スナップショット Snapshot. サーバーがティックごとに送る「今のゲーム状態」の要約。位置、HP、状態などが入っています。たいていは、受信側がすでに持っている状態との差分だけを送ります(デルタ圧縮)。
補間 Interpolation. 受信した2つのスナップショットの間をつないで描き、滑らかに見せる技術。その代わり、少し過去の状態を表示します。
補間バッファ Interpolation buffer. 補間のためにわざと遅らせて描く時間。ジッターや1〜2個のパケットロスを吸収する余裕です。通常はパケット間隔の2倍(1秒に20回受信するなら100ms)で、ジッターが大きくなると自動で延ばすゲームもあります。
Extrapolation, Dead reckoning. 新しいパケットが来ないとき、最後の速度からこの先どこにいるかを推測して描く技術。外れるとワープのように見えるため、多くのゲームは0.25秒前後までしか推測せずに止めます(Sourceエンジンのデフォルト値は0.25秒)。
クライアントサイド予測 Client-side prediction. サーバーの確認を待たずに、自分のキャラクターを先に動かして見せる技術。
サーバー補正 Reconciliation. サーバーの結果が届いたら予測と比べ、自分のキャラクターの位置を修正すること。サーバーが確認した位置から、まだ確認されていない自分の入力を適用し直して計算します。差が大きいと引き戻しのように見えます。
ラグコンペンセーション Lag compensation. サーバーが攻撃の当たり判定をするとき、攻撃者が見ていた過去の時点まで巻き戻して当たったかどうかを確かめる技術。撃たれた側が理不尽に感じないよう、巻き戻す幅に上限を設けます。競技性の高いシューターでは0.2〜0.25秒前後が一般的で、Sourceエンジンのデフォルト値のように1秒まで巻き戻す例もあります。
サーバー権威型 Authoritative server. 最終的な判定はサーバーだけが行うという設計。チートを防げますが、すべての結果がサーバーとの往復を経ます。そのため予測・先行演出で待ち時間を隠します。
ロックステップ Deterministic lockstep. 全員が入力だけをやり取りし、同じターンで同じ計算をする方式。入力に一定の遅延を付け、誰か一人の入力が遅れると全員が待ちます。
サーバー側入力バッファ Server-side input buffer. サーバーがプレイヤーごとに入力を少しためておき、1ティックに1つずつ取り出して使うバッファ。ジッターが大きい人もほかの人からは滑らかに見えますが、その人の行動がサーバーで確定するタイミングはその分遅れます。
リッスンサーバー Listen server. プレイヤー1人のPCが、ゲームをしながらサーバーの役割も兼ねる方式。ホストはPingが0ですが、ホストの回線やPCが遅いと全員がラグの影響を受けます。
フェーズ Phasing. 同じ場所でも、クエストの進行度によって見えるNPCや地形を変える機能。2人のキャラクターの進行度が違えば、片方にだけNPCがいないのは正常です。
ロールバックネットコード Rollback netcode (GGPO). 相手の入力を予測して先に進め、実際の入力が違っていたら過去のフレームまで巻き戻して計算し直す方式。格闘ゲームでよく使われます。DBのロールバックとは別の意味です。
先行入力 Input buffer, spell queue. クールタイムや動作が終わる少し前に押された次の入力を受け付けておき、終わった瞬間に実行すること。連続技の合間に往復時間が挟まらないようにします。
先行演出 Client-side feedback. サーバーの確認を待たずに、アニメーション・サウンド・エフェクトを先に再生すること。ダメージ・報酬のように確定が必要な結果だけ、サーバーの応答を待ちます。サーバーが拒否したら、見せたものを元に戻す必要があります。
TCP Transmission Control Protocol. 順番どおりに、漏れなく届けるプロトコル。失われたパケットを受け取り直すまで、後続のパケットをゲームに渡しません。
UDP User Datagram Protocol. 何の保証もなく、送ったとおりに届けるプロトコル。待ちがない代わりに、パケットロスや順序はゲームが自分で処理します。
信頼性UDP Reliable UDP (KCP, ENet…). UDPの上に、必要な分だけ再送・順序保証を自前で実装した方式。
HOLブロッキング Head-of-line blocking. 先頭の1つが詰まると、後ろのすべてが待たされる現象。TCPで早送りが起きる原因です。
RTO Retransmission timeout. 再送タイマー。TCPがパケットを失ったと判断して送り直すまでに待つ時間。LinuxではPing + 200ms以上で、失敗するたびに2倍になります。
Nagleアルゴリズム Nagle’s algorithm. 先に送ったデータの確認(ACK)が返るまで小さなデータをためておき、まとめて送ることでパケット数を減らすTCPの機能。ゲームではたいていオフにすべきです。
TCP_NODELAY TCP_NODELAY. Nagleアルゴリズムを無効にするソケットオプション。小さなメッセージをすぐに送ります。
遅延ACK Delayed ACK. 受け取ったという確認を少し遅らせて、ほかのデータとまとめて送る機能。Linuxは通常40ms(最大200ms)、Windowsは古いバージョンが200msで、最近のバージョンは40ms。
ソケットバッファ SO_SNDBUF / SO_RCVBUF. OSがソケットごとに持つ、送信・受信の待機領域のサイズ。小さすぎるとあふれ、大きすぎると古いデータがたまって待たされます。
keepalive SO_KEEPALIVE. アイドル接続が生きているかを確認するTCPの機能。デフォルトでは無効で、有効にしてもデフォルト設定では2時間後にようやく確認します。
RST TCP reset. 接続をその場で強制的に切るTCPの信号。まだ送れていないデータは破棄されます。
ハートビート Heartbeat. ゲームが自ら定期的に送る「生きている」という信号。切れた接続の検知や、途中の機器で接続を維持するのに使います。
タイムアウト Timeout. この時間応答がなければ失敗とみなす基準。短すぎると誤判定、長すぎると検知が遅れます。
NAT Network Address Translation. ルーターが家庭内の複数の機器を1つのグローバルIPで外に出し、その接続をNATテーブルに記録する機能。
CGNAT Carrier-grade NAT. 通信事業者が、複数の契約者に1つのIPアドレスを共有させる大規模なNAT。
MTU Maximum Transmission Unit. 一度に送れるパケットの最大サイズ。通常は1,500バイトで、VPN・PPPoEの区間ではさらに小さくなります。
バッファブロート Bufferbloat. 機器がキューを大きくため込みすぎて、遅延が数百msまで膨らむ現象。
SQM Smart Queue Management (fq_codel, CAKE). キューを短く保ち、フローごとに公平に送り出すルーターの機能。バッファブロートの解決策です。
QoS Quality of Service. 重要なトラフィックを優先して送るよう、優先度を付ける機能。
ピアリング Peering. 通信事業者どうしが互いのネットワークを接続する地点。夜に混雑しやすくなります。
BGP Border Gateway Protocol. インターネットでどの経路を使って送るかを、通信事業者どうしで伝え合うためのプロトコル。変わると経路とPingが変わります。
DDoS Distributed Denial of Service. 多数の場所から大量のトラフィックを送りつけ、サービスを停止させる攻撃。
スクラビングセンター DDoS scrubbing center. DDoS攻撃の際、サーバー宛てのトラフィックをいったん引き受けて攻撃を取り除き、正常なトラフィックだけを渡すDDoS対策事業者の拠点。拠点が遠いと経路が長くなります。
ファイアウォール Firewall. 許可された接続だけを通す機器やソフトウェア。接続をセッションテーブルで追跡します。
ロードバランサー Load balancer. 入ってくる接続を、複数のサーバーに振り分ける機器。
セッションテーブル Session table, conntrack. 機器やOSが、現在の接続を追跡するテーブル。サイズに上限があります。
マイクロバースト Microburst. 平均は低くても、1ms以下のごく短い瞬間にトラフィックが集中する現象。
NIC Network Interface Card. サーバーのネットワークカード。
リングバッファ Ring buffer. NICが受信したパケットを、CPUが取り出すまで入れておくバッファ。決まった数のスロットを使い回し、スロットがすべて埋まると新しいパケットは破棄されます。
割り込み Interrupt. デバイスがCPUに「処理すべきことが発生した」と知らせる信号。
RSS Receive Side Scaling. 受信したパケットを複数の受信キューに分け、複数のCPUコアで処理させるNICの機能。
PPS Packets per second. 1秒あたりのパケット数。ゲームサーバーは、帯域幅よりもこの数値で先に限界に達しがちです。
カーネル Kernel. OSの中核。ネットワーク、メモリ、CPUの割り当てを担います。
backlog Listen backlog. サーバーがまだ受け取っていない新規接続の要求が待つキュー。キューが満杯になると、Linuxは新しい要求を黙って破棄し、Windowsは拒否の応答を返します。
TIME_WAIT TIME_WAIT. 先に接続を閉じた側が、遅れて届くパケットに備えて、そのポートの組み合わせをしばらく(Linuxでは60秒)保持する状態。
CPUスチール Steal time. 仮想マシンがCPUを使おうとしたのに、物理サーバーがほかの仮想マシンにCPUを割り当てていたために待たされた時間。topのst値で確認します。
CPUスロットリング CFS throttling. コンテナが決められた周期(CFS period、通常100ms)の中でCPUのクォータ(quota)を使い切ると、次の周期まで強制的に止められること。
ファイルディスクリプタ File descriptor. プロセスが開いたファイル・接続ごとに付く番号(fd)。数に上限があります。
スレッド Thread. プログラムの中で独立して実行される処理の単位。複数のスレッドが同時に実行されることもあります。
コンテキストスイッチ Context switch. CPUが実行中のスレッドを別のスレッドに切り替えること。コストがかかります。
ロック Lock, Mutex. 共有データを一度に1つのスレッドだけが使えるようにする排他制御。
デッドロック Deadlock. スレッドどうしが互いに相手の持つロックを待ち、永遠に止まってしまった状態。
スレッドプール Thread pool. あらかじめ作っておいたワーカースレッドの集まり。すべて使用中だと、新しい処理は待たされます。
非同期I/O epoll, IOCP, io_uring. 入出力の完了を待たずにほかの処理を進め、完了したら通知を受け取る方式。
AOI Area of Interest. 各プレイヤーが「見える範囲」。この範囲内の変化だけを送って通信量を減らします。誰が範囲内にいるかを調べるコストを下げるため、通常はマップをグリッドに分けて近くのセルだけを調べます。
ブロードキャスト Broadcast, fan-out. 1つの変化を、それが見える複数のプレイヤーに送ること。集まった全員が互いを見ている場合、送る量は人数の2乗で増えます。
GC Garbage collection. 使い終わったメモリを自動で回収する機能。GCの間、プログラムが止まることもあります。
ヒープ Heap. プログラムが実行中に、必要に応じて確保して使うメモリ領域。
メモリリーク Memory leak. 使い終わったメモリを解放しないため、使用量が増え続けるバグ。GCがあっても、使い終わったオブジェクトをどこかで参照し続けていると起きます。
スワップ Swap, paging. RAMが足りず、メモリの一部をディスクに退避すること。退避したメモリを再び使うときは、RAMより1,000倍以上遅くなります。
OOM Killer Out-of-memory killer. メモリが枯渇すると、Linuxがメモリを最も多く使っているプロセスを選んで強制終了する機能。コンテナでは、メモリ上限に達しただけでも発動します。
キャッシュミス Cache miss. CPUに近いキャッシュにデータがなく、遅いメモリまで取りに行かなければならないこと。
IOPS I/O operations per second. ディスクが1秒間に処理できる読み書きの回数。クラウドのディスクは、支払った料金に応じて上限が決まります。
fsync fsync. データがディスクに確実に書き込まれるまで待つ命令。通常の書き込みはまずOSのメモリに入り、あとからディスクに書き出されるため、その間にサーバーの電源が落ちると失われることがあります。fsyncは安全ですが遅くなります。
バーストクレジット Burst credits. クラウドのディスク・サーバーが一時的にベースライン以上の性能を出せるように、ためておくクレジット残高。使い切るとベースライン性能に落ちます。
インデックス Index. DBの索引。ないとテーブル全体を読む必要があります。
フルスキャン Full table scan. インデックスを使わずに、テーブルの全行を調べる検索。
実行計画 Query plan. DBがクエリをどの順序で、どのインデックスを使って処理するかを決めた方法。コードが同じでも、DBが実行計画を変えると同じクエリが急に遅くなることがあります。
トランザクション Transaction. 「すべて成功するか、すべて失敗するか」を1つにまとめたDBの処理。取引は必ずトランザクションで処理します。終わるまで更新した行をロックしておくため、短いほど良いです。
コネクションプール Connection pool. あらかじめ確立しておいたDB接続の集まり。すべて使用中だと、新しいリクエストは待たされます。
ホットスポット Hot row. 多くのリクエストが同時に更新しようとする1つの行。ロック競合の原因。
レプリケーション遅延 Replication lag. レプリカのDBがプライマリのDBに追いつけず、遅れている時間。
ロールバック Rollback. 保存が取り消されて、以前の状態に戻ること。プレイヤーは「アイテムが消えた」と感じます。
キャッシュ Cache (Redis etc.). よく使うデータを、高速な場所にコピーしておくもの。DBの負荷を減らします。
チェックポイント Checkpoint. DBがメモリにためた変更分を、定期的にまとめてディスクに書き込む処理。その瞬間、保存・参照が一時的に遅くなることがあります。
フェイルオーバー Failover. プライマリのサーバーやDBが落ちたとき、スタンバイ側に切り替えること。切り替え中はしばらく保存できず、レプリケーションが遅れていれば直近のデータが失われることがあります。
MVCC Multi-version concurrency control. 読む側と更新する側が互いをブロックしないよう、DBが古いバージョンを一時的に保持する方式。長時間開いたままのトランザクションがあると、古いバージョンがたまって遅くなります。
キャッシュスタンピード Cache stampede. キャッシュが一斉に切れて、リクエストがオリジン(DB)に殺到する現象。
ゲートウェイ Gateway. クライアントの接続を受けて、後ろのゲームサーバーに中継する中間サーバー。
サーキットブレーカー Circuit breaker. 失敗が続くサービス呼び出しを一時的に遮断し、すぐに失敗として扱うことでカスケード障害を防ぐ仕組み。しばらくしてから1〜2回試しに呼び出し、復旧していれば呼び出しを再び許可します。
カスケード障害 Cascading failure. 1か所の障害が、呼び出しチェーンをたどってほかのサービスに広がること。
オートスケーリング Autoscaling. 負荷に応じてサーバー台数を自動で増減する機能。増えるまでに時間がかかります。
ウォッチドッグ Watchdog. サーバーが止まっていないかを監視するタイマー。ゲームループが決められた時間(数秒〜数十秒)以上止まると、状態の記録(ダンプ)を残してサーバーを強制終了し、再起動させます。
利用率 Utilization. ワーカー(CPUコア・スレッド・DBコネクションのように、リクエストを処理する主体)がビジーな時間の割合。80〜90%を超えると待ちが急激に増えます。
p99 99th percentile. 100回のうち99回はこれより速く、1回はこれより遅い値。平均よりも体感のラグをよく表します。
V-Sync Vertical sync. 画面のリフレッシュ周期に合わせてフレームを出力する機能。ティアリング(画面のずれ)はなくなりますが入力遅延が生じ、FPSがリフレッシュレートを下回ると60と30の間を行き来してカクつくこともあります。
可変リフレッシュレート VRR, G-Sync, FreeSync. フレームの準備ができたタイミングに合わせて、モニターが画面を更新する機能。V-Syncで60と30を行き来して起きるカクつきと入力遅延を減らします。
アンチチート Anti-cheat. ゲームのチート(不正改造)を防ぐセキュリティモジュール。定期的な検査やサーバーとのハートビートが失敗すると、カクつきや切断を引き起こすこともあります。
オーバーレイ Overlay. チャット・録画・FPS表示などのソフトが、ゲーム画面の上に描き重ねる機能。ゲームの描画処理に割り込むため、カクつきの原因になることがあります。
シェーダーコンパイル Shader compilation. グラフィック効果のプログラムをGPU用に変換する処理。事前に済ませておかないと初めて表示するときに画面が一瞬止まり、グラフィックドライバーを更新すると保存済みの結果が無効になってやり直します。
メインスレッド Main thread, Game thread. ゲームロジックの計算と描画の準備を順番に処理する、ゲームの中心となるスレッド。ここで時間のかかる処理が1つでもあると、その間画面が止まります。
タイマー分解能 Timer resolution. OSが、スリープ中のプログラムを起こせる最短の間隔。Windowsのデフォルト値は15.6msなので、プログラムが個別に変更しなければ「1ms後に起こして」と頼んでも遅れて起きます。
サーマルスロットリング Thermal throttling. 端末が熱くなると、自らCPU・GPUのクロックを下げる保護機能。スマホでは数分〜数十分ゲームをすると頻繁に起きます。
VRAM Video memory. グラフィックカードに搭載された専用メモリ。テクスチャやモデルをここに載せて描画します。足りなくなると、PCのメモリと遅い経路でやり取りするためカクつきます。
ネットグラフ Net graph. ゲーム画面にPing・パケットロス・FPS・ティックをリアルタイムのグラフで表示する、開発・デバッグ用の表示。ラグ報告の動画に一緒に映っていると、原因の特定がずっと楽になります。
再送率 Retransmission rate. 送信したTCPパケットのうち、再送した割合。公的な基準はありませんが、サーバー全体の平均が0.1%未満なら健全な部類で、1%を超えると多くのユーザーがラグを感じやすくなります。普段の値の何倍に増えたかもあわせて見ます。
SACK Selective ACK. 受信側が「この範囲は受け取り、この部分だけ抜けている」と詳しく伝えるTCPの機能。複数のパケットを失っても、一度に回復できます。
RACK-TLP Recent ACK, Tail Loss Probe. 時間を基準にロスを判断し、しばらくACKが来なければ末尾のパケットをもう一度送って回復を早めるTCPの機能。最新のLinux・Androidのデフォルトです。WindowsはWindows 10(1607)・Server 2016からTLPとRACKがデフォルトで、失った再送パケットまで回復する新しいRACKはServer 2022からです。SACKが有効な接続でのみ動作します。
不要な再送 Spurious retransmission. 失われていないのに、遅れて届いたり順序が入れ替わったりしたためにロスと誤認して送り直したもの。回線を無駄にし、送信量を不必要に絞ってしまいます。
ゼロウィンドウ Zero window. 受信側のバッファが満杯になり、「しばらく送らないで」と通知した状態。再送のように見えますが回線は正常で、受信側のプログラムが時間内に読み出せていないことが原因です。
thin stream Thin stream. ゲームのように、小さなパケットをまばらに送る接続。高速再送のきっかけとなる信号が集まりにくく、ロスのときに長く止まります。
ポリサー Policer. 決められた速度を超えたパケットを、キューに入れずにすぐ破棄する帯域制限の方式。キューに入れてからゆっくり送り出す方式はシェーパーと呼びます。
ペーシング Pacing. 送るパケットを一度に吐き出さず、時間的に均等に分けて送ること。小さなバッファがあふれるのを防ぎます。
ECN Explicit Congestion Notification. 輻輳時にパケットを破棄せず「輻輳あり」の印を付け、送信側に速度を落とさせる機能。ロスなしで輻輳を伝えます。両端と、混雑している区間の機器がすべて対応していないと効果がありません。
MSS Maximum Segment Size. TCPが1つのパケットに入れるデータの最大サイズ。通常は1,460バイトで、トンネル区間に合わせて小さくするとMTUブラックホールを防げます。
ハンドオーバー Handover. 移動中のスマホが、接続先の基地局を切り替えること。
パーセンタイル Percentile (p50, p95, p99). 値を小さい順に並べたとき、何%目に来る値か。p50は中央値、p99は100回のうち最も遅い1回付近の値です。平均では隠れてしまうスパイクがわかります。
テールレイテンシ Tail latency. 大半は速いのに、ときどき発生する長い遅延。平均にはほとんど表れませんが、ユーザーがラグとして記憶するのはこの部分です。
外形監視 Synthetic monitoring. 実際のユーザーの代わりに、計測用の端末・サーバーが決まった場所から定期的にping・tracerouteなどを送り、経路の品質を測ること。RIPE Atlasが代表的な公開ツールです。
集計間隔 Aggregation interval. グラフの1点が、何秒・何分の値をまとめたものか。間隔が長いほど、短いスパイクが平均に埋もれて見えにくくなります。
ポストモーテム Postmortem. 障害が収まった後に、何が起き、なぜ起き、何を変えるかをまとめた文書。責任追及より再発防止を目的に書きます。
C-state CPU idle state. CPUが休んでいるときに入る省電力状態。深い状態ほど電力を節約できますが、復帰に時間がかかります。
ライブマイグレーション Live migration. クラウドがホストのメンテナンスなどのために、実行中の仮想マシンを別のホストに移すこと。移す瞬間に一時的に止まることがあります。
SNAT Source NAT. 送信パケットの送信元アドレスを、グローバルアドレスに書き換えるNAT。1つのグローバルアドレスで使えるポート数には上限があり、使い切ると新しい接続が失敗します。
NATゲートウェイ NAT gateway. プライベートネットワーク内のサーバーがインターネットに出るとき、1つのグローバルアドレスを共有させるクラウドの仕組み。宛先ごとの同時接続数に上限があります。
低軌道衛星インターネット LEO satellite internet. 高度数百〜数千kmの衛星群で接続するインターネット。静止軌道衛星より遅延はずっと短いものの、接続する衛星が切り替わるときに遅延が跳ねることがあります。
GeoIP IP geolocation. IPアドレスから国・都市・通信事業者を推定するデータベース。誤った項目や古い項目があり、遠い地域のサーバーに割り当てられる原因になることもあります。
TLS証明書 TLS certificate. サーバーが本物であることを証明する電子文書。有効期限があり、期限が切れると暗号化通信の確立に失敗して接続できなくなります。
フレーム生成 Frame generation. グラフィックカードが実際に描いたフレームの間に予測したフレームを挟み込み、FPSを上げる技術。画面は滑らかになりますが、入力から画面表示までの遅延は増えることがあります。
参考文献
資料616件、発行元83組織。標準規格の文書、カーネル・OS・クラウド・エンジン・DBの公式ドキュメント、論文、開発元の技術記事です。
Microsoft 85
Linux kernel 62
IETF 59
AWS 51
MySQL 32
Unity 26
PostgreSQL 25
ACM 20
Epic Games 19
Android (Google) 17 Android common kernels Android (Google) 5.10〜6.18の共通カーネルが並行してサポートされ、以前のプラットフォーム向けのカーネル(例:android14-6.1)を新しいAndroid端末の発売やアップグレードに使える ApplicationExitInfo Android (Google) REASON_LOW_MEMORY:システムの低メモリキラーがアプリのプロセスを終了させた(非対応の端末ではREASON_SIGNALED・SIGKILLとして報告) Cached apps freezer Android (Google) Android 14以降は、キャッシュ状態になったアプリのプロセスを10秒後に凍結し、凍結されるとすべてのスレッドが止まる Crashes Android (Google) 処理されない例外やシグナル(SIGSEGVなど)でアプリが予期せず終了するのがクラッシュ。Play ConsoleのAndroid vitalsで集計 Frame Pacing library Android (Google) 60Hzの画面で新しいフレームがなければ前のフレームを再表示する。30FPSのゲームのフレームタイムが49・16・33msのようにばらつく例 Memory allocation among processes Android (Google) AndroidはメモリをzRAMに圧縮してしのぎ、足りなくなると低メモリキラーがプロセスを終了させる。フォアグラウンドのアプリが終了するとクラッシュのように見える Network security configuration Android (Google) 証明書ピンニングを使うなら、鍵の差し替え・CAの変更に備えて予備の鍵も組み込む必要があり、そうしないとアプリを更新するまで接続できなくなる Optimize network access Android (Google) 無線状態の遷移遅延とtail時間は、無線技術(3G・LTE・5G)と通信事業者の設定によって異なる。3Gの例:低電力→最大電力で約1.5秒、待機→最大電力で2秒以上 Read network state Android (Google) デフォルトネットワークが変わると、新しい接続は新しいネットワークを使い、以前のネットワークの接続は最終的に強制的に切られる。registerDefaultNetworkCallbackで切り替えを検知 Security with network protocols Android (Google) サーバーが中間証明書を含めずに送ると、AndroidアプリはSSLHandshakeExceptionで失敗するが、PCのブラウザは保持している中間証明書で補うためエラーにならないことがある、openssl s_clientでサーバーが送るチェーンを確認 Slow rendering Android (Google) 60FPSを出すには1フレームを16ms以内に描画する必要があり、遅れるとフレームが飛ばされてカクつき(jank)として見える Slow Sessions (games only) Android (Google) Android vitalsは、ゲームのフレームが50ms(20FPS)・34ms(30FPS)を超えると低速フレームとみなす TelephonyDisplayInfo Android (Google) OVERRIDE_NETWORK_TYPE_NR_NSA:LTEに接続しながら、5G(NR)とのデュアルコネクティビティ(EN-DC)が可能な場合、または接続している場合のネットワーク表示 Thermal API Android (Google) 端末は高い性能を限られた時間しか維持できず、その後は発熱でスロットリングされる。発熱状態を見て、先に負荷を下げることを推奨 Wi-Fi low-latency mode Android (Google) 低遅延モードではWi-Fiの省電力を無効にする。検索・ローミング設定の最適化は端末メーカーの実装による WifiManager Android (Google) WIFI_MODE_FULL_LOW_LATENCY(API 29、Android 10):APに接続していて、画面がオンで、アプリがフォアグラウンドにあるときだけ適用される低遅延Wi-Fiロック Window.setPreferMinimalPostProcessing Android (Google) ゲームのように遅延が重要なウィンドウは、ディスプレイに最小限の映像処理を要求する。HDMI接続ならALLM・Game Content Typeの信号を送り、テレビを低遅延モードに切り替える
Linux man-pages 15
Microsoft Azure 12
Oracle 9
Redis 9 Diagnosing latency issues Redis 要求を1つのスレッドが順番に処理するため、遅いコマンドが後ろをすべて止める、KEYSの代わりにSCAN、forkは物理サーバー・最新VMの実測で1GBあたり約9〜13ms、THPはfork後のコピーで遅延・メモリが急増、同じ秒に大量の期限切れが起きると停止 High availability with Redis Sentinel Redis プライマリが落ちるとレプリカを昇格させる自動フェイルオーバー INFO Redis keyspace_hits・keyspace_misses(キー参照の成功・失敗数)、expired_keys(期限切れになったキーの数)、uptime_in_seconds(起動からの経過時間) KEYS Redis 本番環境では細心の注意を払って使うこと、大きなDBでは性能を大きく損なうおそれがある(エントリーモデルのノートPCでキー100万個に40ms) Redis CLI Redis --bigkeys:キー空間を走査して大きなキーを探す Redis latency monitoring Redis latency-monitor-thresholdのデフォルトは0(無効)、LATENCY LATEST・LATENCY DOCTOR、fork・expire-cycleのようなイベントごとの遅延を記録 Redis persistence Redis RDBスナップショットを数分ごとに作る場合、異常終了時には直近数分のデータを失う覚悟が必要 SLOWLOG Redis slowlog-log-slower-thanを超えたコマンドを記録するスローログ、実行時間にはクライアントとのI/Oは含まれない UNLINK Redis キーを即座に切り離し、メモリの回収は別スレッドで行う非同期削除
Cloudflare 8
Gaffer On Games 7
Google Cloud 7
iproute2 7
Apple 6
Bufferbloat.net 6
Google 6
Microsoft SQL Server 6
Wireshark 6
.NET 5
OpenJDK 5
systemd 5
ITU 4
sysstat 4
Valve 4
AMD 3
CCP Games 3
chrony 3 chrony – Frequently Asked Questions chrony makestep 1 3のように起動直後の数回だけステップを許可するのが推奨、一時停止から再開した仮想マシンは時刻がずれたまま復帰することがある chrony.conf(5) chrony logchange:この値(デフォルト1秒)より大きく時刻を調整するとsyslogに記録 chronyc(1) chrony chronyc trackingのSystem time(NTP時計とシステム時計の差)、Last offset(最後の補正時に推定したオフセット)、Ref time(時刻ソースの最後の測定値を反映した時刻)
Go 3
IEEE 3
Intel 3
IO Visor 3
Kubernetes 3
NVIDIA 3
perf 3
Riot Games 3
RIPE NCC 3
APNIC 2
Istio 2 Istio Standard Metrics Istio istio_request_duration_milliseconds(HTTP・gRPCリクエストの処理時間の分布)、reporterラベルで送信側(source)・受信側(destination)のプロキシを区別 Performance and Scalability Istio サイドカーモードでは、リクエストは送信側と受信側のサイドカープロキシを順に経由、機能を足すほどプロキシ内の処理経路が長くなり、テレメトリ収集が次のリクエストの待ち時間を延ばす
Let's Encrypt 2
MaxMind 2
numactl 2
OpenSSL 2 openssl-s_client OpenSSL -showcerts:サーバーが送った証明書の一覧を送られた順のまま表示(検証済みのチェーンではない) openssl-x509 OpenSSL -enddate:証明書の有効期限(notAfter)を出力、-checkend:指定した秒数以内に期限が切れるかを検査
SK텔레콤 2
Solidigm 2
Square Enix 2
USENIX 2
util-linux 2
Amazon Builders' Library 1
Apache Software Foundation 1 Asynchronous loggers Apache Software Foundation 非同期ロギングは短い急増をキューで吸収するが、出力が遅い状態が続くとキューが埋まり、最も遅い出力の速度まで落ちるか、ポリシーに従ってログを破棄(Discard)
coreutils 1
Envoy 1 What is Envoy Envoy Envoyはすべてのアプリケーションサーバーの横で別に動くプロセスで、アプリはlocalhostのEnvoyを経由して通信
ethtool 1
Frontiers 1
Game Developer 1
gdb 1
GDC 1
GGPO 1
GNU Project 1
HDMI Licensing Administrator 1 Auto Low Latency Mode (ALLM) HDMI Licensing Administrator ALLMは、機器がディスプレイを低遅延モード(一般にゲームモード)へ自動で切り替えられるようにする。低遅延モードでは、遅延を減らすためにテレビの映像処理の一部を止める
id Software 1
iputils 1
IRTF 1
jemalloc 1
Juniper Networks 1 Flow-Based Sessions Juniper Networks 実験の企業ファイアウォール:SRXファイアウォールのデフォルトのセッションタイムアウトはTCP 1,800秒(30分)、UDP 60秒
Lua.org 1 Lua 5.4 Reference Manual Lua.org インクリメンタルモードは回収を小さなステップに分けて実行の合間に挟み込み(ステップを大きく取ると全停止)、世代別モードのmajor回収はすべてのオブジェクトをたどる全停止、collectgarbage("count")はLuaが使っているメモリの総量(KB)
Meta 1
mtr 1
net-tools 1
netfilter 1
Netflix 1
Network Time Foundation 1
OpenWrt 1
procps-ng 1
Red Hat 1
Seagate 1
Starlink 1 Improving Starlink’s Latency Starlink 米国ピーク時間帯の中央値48.5ms→33ms、最も遅い1%(p99)150ms超→65ms未満(2024年)、衛星1区間の伝搬1.8〜3.6ms、レーザーリンクを経由すると遅延が加わり、地上局からインターネット接続点(PoP)までの距離も遅延の要因
VLDB Endowment 1
과학기술정보통신부 1