カクつき
動きが滑らかでなく、短く止まっては動くのを繰り返します。 Ping値に問題がなければ自分のPCのフレーム(クライアント・OS)の問題、PingがばらつくならWi-Fi・回線のジッターの可能性が高いです。ただしゲーム内のPing表示はたいていフレームごとに回るゲームループの中で計測しているため、フレームが跳ねるとPingの数値も一緒に跳ねることがあります。
画面がカクつく、キャラクターがワープする、接続が切れるといった現象の原因を、自分のゲーム画面からサーバーのデータベースまで13の層に分けて説明します。原因ごとに確認方法と担当チームを記載しており、実験で条件を変えながら確かめられます。MMOの事例を中心に書いていますが、ほとんどはジャンルを問わずオンラインゲーム全般に当てはまります。
原因は100を超えますが、ラグを生む要因は大きく4つにまとめられます。パケットが遅れて届く、ばらばらの間隔で届く、まったく届かない、そして誰かが計算を止める。ゲームはこれらの要因を隠すためにさまざまな技術を使っていて、隠しきれなかった跡が、私たちが目にするラグの「形」です。
MMOで自分の画面に見えている世界は、サーバーから届いたパケットをもとに描き直した画面です。サーバーはゲームによって異なりますが、通常1秒に10〜30回ゲームの状態を計算し(この1回をティックと呼びます)、その結果のうち各プレイヤーの周囲の変化だけを選んでパケットで送ります。自分のPCは届いたパケットを読んで画面を描きます。つまりラグの大半は、「パケットが時間どおりに届かなかったこと」をゲームがどう見せるかの問題です。
4つの要因に当てはまらないケースもあります。サーバーと自分のPCで同じ処理の計算結果が食い違うと(移動ルールの違い、バグ)、回線が正常でも引き戻しや表示されない現象が起きます。こうしたラグは、Pingに関係なく同じ場所・同じ操作で繰り返し起きることが手がかりです。
宅配便で考えてみてください。配送にいつも3日かかるなら遅延、1日で届くものもあれば5日かかるものもあるならジッター、荷物が消えたらパケットロス、物流センターが閉まってしまったらストールです。ゲームは「荷物が遅れたり届かなかったりしたら、前後の荷物から推測して埋める(補間・外挿)」「届かなければもう一度送ってもらう(再送)」といった方法でしのぎます。
ラグの話はほとんどがミリ秒(ms、1/1000秒)単位です。下の表の数字をいくつか覚えておくだけで、ゲーム開発チームやインフラチームの話がずっと分かりやすくなります。
| 基準 | 時間 | 意味 |
|---|
CPU、ディスク、データベース、ルーター、通信事業者の回線。層は違っても構造は同じです。リクエストを処理するワーカー(CPUコア、スレッド、DBコネクションなど)があり、その手前にキューができます。ワーカーが空いていればキューは空ですが、忙しさ(利用率)が80〜90%を超えるとキューは急激に長くなります。ワーカー1つにリクエストがランダムに届く場合、平均待ち時間は利用率50%で処理時間と同じ、80%で4倍、90%で9倍になります。「CPUはまだ10%余っているのに、なぜラグるんですか?」の答えがここにあります。しかも監視画面のCPU値はふつう複数コアと1〜5分間を平均した値なので、1つのコアだけが100%になっている状況や、数秒間だけ負荷が集中した瞬間は見えなくなります。
ゲーム画面を描く自分のPC・スマホから、家庭内ネットワーク、通信事業者、データセンター、サーバーとデータベースまで、オンラインゲームのプレイ中にラグを生む原因を扱います。ゲーム画面を映像として受け取るクラウドゲーミング、別サービスとして動くボイスチャット、アップデート・ダウンロードの速度は仕組みが異なるため扱いません。ただし、その中のネットワーク側の原因(Wi-Fi、バッファブロート、回線の混雑など)はここにある原因と同じです。
スキルボタンを押すと、その信号は自分のPC、家庭内ネットワーク、通信事業者、データセンターを通ってサーバーに届きます。サーバー内の複数の層で処理された結果は、同じ層を逆にたどって画面に描かれます。全部で13の層があり、どの層で詰まってもラグになります。下のマップで層を押すと、その章に移動します。
サーバー1台、回線1本、自分のPC1台でできた小さなシミュレーションです。条件を1つずつ壊しながら、カクつき、ワープ、引き戻し、早送り、スローモーション、入力遅延、フリーズ、切断がそれぞれどうやって生まれるのかを確かめてください。パケットタイムラインは、パケットがいつ送られていつ届いたかを線で示します。線が傾いているほど時間がかかったことを表し、×は消えたパケットです。
プレイヤーは「ラグい」としか言いませんが、ラグの形は原因についてかなり多くのことを教えてくれます。各症状の小さな図は、画面内のキャラクターが通った跡です。点が重なっていれば止まったこと、間隔が開いていれば速くなったか位置が飛んだことを表します。
動きが滑らかでなく、短く止まっては動くのを繰り返します。 Ping値に問題がなければ自分のPCのフレーム(クライアント・OS)の問題、PingがばらつくならWi-Fi・回線のジッターの可能性が高いです。ただしゲーム内のPing表示はたいていフレームごとに回るゲームループの中で計測しているため、フレームが跳ねるとPingの数値も一緒に跳ねることがあります。
キャラクターが途中の移動なしに、離れた位置へ一瞬で移ります。 たいていは、しばらくパケットが途切れたことを意味します。パケットロス、回線の瞬断、サーバーの停止、外挿の失敗を疑います。ほかの人は問題ないのに一人だけワープするなら、まずその人の回線を疑います。
自分のキャラクターが前に進んでいたのに、今通ってきた位置へ引き戻されます。 自分の画面(予測)とサーバーの判定が食い違っています。自分の入力がサーバーに届かなかったか(パケットロス)、サーバーの移動検証に弾かれたか、双方の移動計算が一致していません。
止まっていた画面が動き出すと同時に、たまっていた動き・ヒット・ダメージが一気に早回しで流れます。 どこかでたまっていたパケットが、一度に解放されました。TCPの再送待ち、サーバーの追いつき処理、クライアントの処理遅れが代表的です。
すべてがゆっくり動きます。スキルの発動やモンスターの移動が間延びして見えます。サーバーの設計によっては、速度はそのままでカクつき・ワープとして現れることもあります。 サーバーがティックを時間内に終えられていません。回線は正常なのでゲームの外で測ったPingは変わらず、ゲーム内のPingはサーバーの処理待ちが含まれていると少し上がることがあります。人数の急増、視界計算、ブロードキャスト、メモリ不足を確認します。
押してから結果が出るまでに時間がかかります。画面そのものは滑らかな場合もあります。 往復時間(Ping)が長いか、どこかでキューが詰まっています。距離、ルーターのキュー、Nagle(小さなパケットをまとめて送るTCPの機能)、サーバーのキューを確認します。Pingが低いのにいつも操作が重いなら、V-Sync・低いFPSのような自分のPC側か、操作のたびにサーバーの確認を待つ設計(同期方式の章)を疑います。
画面内のすべてが少しの間(0.5秒〜数秒)止まってから、また動き出します。 サーバーが丸ごと止まったか(GC、デッドロック、同期呼び出し)、回線が一瞬切れたか、自分のPCが止まりました。
確かにやったはずの行動がなかったことになるか、結果がしばらく経ってから覆ります。 リクエストが消えたか(パケットロス、キューのあふれ)、サーバーが自分の画面とは違う判定をしたか(判定タイミングのずれ、先行演出の後の拒否)、保存の途中で失敗しました(DBのロック・障害、サーバーのクラッシュ)。
プレイ中に接続が切れ、ログイン画面や再接続の画面に戻されます。 タイムアウト時間内にパケットが一つも届きませんでした。長い回線断、アイドルタイムアウト、サーバーのクラッシュ・再起動、タイムアウトより長く止まったサーバーや自分のPC(長いロード)を確認します。案内なしにゲーム自体が終了したなら、接続よりもクライアントの強制終了(クラッシュ、メモリ不足)を先に疑います。
ゲームに入れない、またはロード・入場画面で止まったままになります。 新しい接続を受け付ける場所(サーバーの接続待ちキュー、ファイアウォール、ログインサーバー、DB)が満杯になっています。メンテ明けに特に多く起きます。
いるはずのNPC・モンスター・プレイヤーが自分の画面にだけいない、またはすでに消えたオブジェクトが自分の画面にだけ残っています。 速度の問題というより、パケットが一つ抜けたか描画に失敗した状態です。チャンネル・フェーズの違い、出現・消滅通知の欠落、ロード中の破棄、アセットのロード失敗を確認します。視界から外れて戻ってきたときに表示されるかどうかが、決定的な手がかりです。
Ping 150msでもまったく気にならないゲームもあれば、60msでももっさりするゲームもあります。アクションゲームに限った話ではありません。同じ回線なら、この差はたいていクライアントとサーバーが「何を、いつ、誰が決めるか」の取り決め、つまり同期設計から生まれます。そして、その一部は意図した選択で、一部は本当に作りが悪いものです。
ネットワークゲームはどれも同じ問題を解いています。サーバーと自分のPCの間には必ず時間差があり、どちらかが「まだ確定していないもの」をどう扱うかを決めなければなりません。選択肢は大きく4つです。
そのため、Pingへの敏感さを大きく左右するのは、ジャンルよりも次の2つの問いです。核となる1つの行動が、サーバーとの往復を何回待つか。そして、ゲームのルールが許す時間が「Ping+人の反応時間」より十分に長いかです。
| 方式 | どう動くか | よく使われる場面 | Ping 150msでの見え方 | 弱点 |
|---|---|---|---|---|
| リクエスト・レスポンス サーバー確認後に表示 | 押すとサーバーに問い合わせ、応答が来てから演出する。 | ターン制・カード・放置系、ショップ・取引・製作のUI、古いMMOのスキル・アイテム使用 | すべての行動が0.2秒ほど遅れて始まる。ターン制ならほぼ気づかない | 連続した行動、1画面に往復が何回もあるUI |
| 状態同期+補間 サーバー権威型 | サーバーがゲームの状態をティックごとに送り、クライアントは2つの状態の間をつないで描く。 | ほとんどのMMOでのほかのプレイヤー・モンスターの表示 | ほかの人は約0.2秒前の姿。ふだんはほとんど気づかない | ジッター(到着間隔のばらつき)・パケットロス → ワープ、低いティックレート |
| クライアントサイド予測+サーバー補正 | 自分の入力はすぐに反映し、サーバーの結果が来たら比べて修正する。 | FPS、アクションMMO、ほとんどのMMOの移動 | 自分の操作は即座に反映。ときどき短い引き戻し | サーバーと計算が食い違うと補正が頻発 |
| ラグコンペンセーション サーバーが巻き戻して判定 | サーバーが、攻撃者が見ていた過去の時点に巻き戻して命中を判定する。 | FPS、ノンターゲットアクション | 撃った側は公平に感じるが、撃たれた側は「遮蔽物に隠れたのに当たった」 | 撃たれた側の理不尽感。攻撃者のPingが高いほど大きく巻き戻すため悪化 |
| コマンド・目的地の同期 | 「ここへ行け」「この対象を攻撃」のように意図だけを送り、両側がそれぞれ計算する。 | クリック移動のMMO、タブターゲットの戦闘、一部のMOBA | 動き出しが少し遅れるだけで、移動と攻撃はなめらか | 経路・結果が食い違うと補正が必要 |
| イベント予約 サーバー時刻ベース | 「サーバー時刻Tに開始」のように未来の時刻と一緒に知らせ、それぞれがその時刻に再生する。 | レイドボスの攻撃パターン、カットシーン、定時イベント | 予兆がPingより長ければ事実上影響なし | 予約した時刻より遅れて届くと、冒頭部分を飛ばす |
| 決定論的ロックステップ | 全員の入力を集めて、同じターンにまったく同じ計算をする。入力には固定の遅延を付ける。 | RTS(StarCraft系)、一部の協力・パズルゲーム | すべての入力が一定に遅れる(押した瞬間の効果音・表示でごまかす)。ジッターが大きいと全員が止まる | ジッター・パケットロス、最も遅い1人 |
| ロールバック 予測してから巻き戻し | 相手の入力を予測して先に進め、外れたら過去に巻き戻して計算し直す。 | 格闘ゲーム(GGPO系)、一部のアクション・スポーツ | 操作感はほぼ即座(ふつうは1〜3フレームの入力遅延)。相手の動きがときどき数フレーム飛ぶ | Pingが大きいと巻き戻し幅が大きくなり、ワープのように見える |
| クライアント権威型 | それぞれが自分の結果を決め、サーバーは中継・記録だけをする。 | 一部のモバイル・カジュアル、P2P・リレー構成 | 自分の画面は快適。ほかの人の画面と結果が食い違う | チート、「自分は当てたのに当たっていない」 |
実際のゲームは、これらの方式を組み合わせて使います。移動は予測、スキルは先行演出の後に確定、ボスの攻撃パターンはイベント予約、取引はリクエスト・レスポンスのように、行動ごとに使い分けるのがふつうです。
1. 1つの行動に往復が一度も挟まらない。ボタンを押したらアニメーション・効果音・エフェクトをすぐに始め(先行演出)、サーバーの結果はダメージの数字のように遅れても目立たない部分にだけ使います。
2. ゲームのルールが許す時間がPingより十分に長い。ボスの予兆が1〜2秒あれば、パケットが0.2秒ほど遅れて届き、人の反応に0.25秒使っても十分によけられます。自分のスキルに詠唱時間があれば、詠唱バーがたまる間にサーバーの確認も終わるので、待ち時間が詠唱時間の中に隠れます。タブターゲットのMMOがPingに鈍感な最大の理由です。逆に、0.5秒前後の短い予兆は、Pingが150msあるだけで見てからよけるのが難しくなります(下の判定の受付時間の実験)。
3. 連続した行動を先に受け付けておく。クールタイムが終わる前に次のスキルを押しても受け付けておく先行入力(スキルキュー)があれば、連携の間に往復時間が挟まりません。
4. ジッターを吸収する。補間バッファやサーバー時刻ベースの演出は、「たいてい150ms、ときどき250ms」かかって届くパケットを、常に250msほど遅れた一定の流れに変えます。少し過去を見る代わりに、なめらかになります。人は一定の遅れにはすぐに慣れますが、ばらつきにはなかなか慣れません。よくできたゲームは、ジッターの増減に合わせてバッファの長さを自動で伸び縮みさせます。
5. 判定が「自分が見たもの」と一致する。回避・命中をプレイヤーが見た時点を基準に判定するか(ラグコンペンセーション)、そもそも位置が重要でないルール(ターゲット指定)を使います。
6. 1人の遅延がほかの人を待たせない。サーバー権威型の構成では、自分のPingが悪くてもほかの人は問題ありません。ロックステップやホスト型の構成では、最も遅い1人が全員の体感を決めます。
Pingに敏感な理由は、意図した設計の場合もあれば、作りが悪いせいの場合もあります。
ボタンを押しても、サーバーの応答が来るまでアニメーションも音も出ません。Pingがそのまま反応速度になります。
なぜ: スキル・移動・アイテム拾いを、サーバーの確認が来てから再生 → すると: 押した瞬間から、往復時間 + ティック待ちの間まったく反応なし → 画面では: Pingが150msなら、すべての行動が0.2秒ずつ遅れてもっさりする
症状: 入力遅延 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
1回の操作でサーバーとの往復が順番に何回も必要になると、Pingがその回数分だけ積み重なります。
なぜ: ショップを開く → 一覧を要求 → 価格を確認 → 購入 → インベントリ更新を、それぞれ別々にリクエスト → すると: 前のリクエストの応答を受け取ってから次のリクエストを送る → 画面では: Ping 150msで1回の購入に1秒近くかかる。ロードがやけに長い
症状: 入力遅延, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
前のスキルがサーバーで終わったという確認を受けるまで次のスキルを押せないと、連携のたびに往復時間が挟まります。
なぜ: 次のスキル入力を「前のスキルの確定後」にだけ受け付ける → すると: スキルとスキルの間に、毎回Pingの分だけ空白の時間ができる → 画面では: 連携の間に毎回すき間ができ、Pingが高いほどDPSが下がる
症状: 入力遅延, 不発・ロールバック · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
回避・パリィ・ガードのように反応すべき時間が短いと、Pingがその時間を削ってしまい、よけられない攻撃が生まれます。
なぜ: ボスの攻撃の予兆0.5秒、パリィの判定0.2秒のような短い判定の受付時間 → すると: 予兆を見るのが遅れ(下りの遅延 + 補間)、自分の入力も遅れて届く(上りの遅延 + ティック待ち) → 画面では: 確かによけたのに当たる、パリィが不発になる
症状: 不発・ロールバック, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
サーバーが「今のサーバー上の位置」だけで命中を判定すると、自分が見た画面と判定が食い違います。
なぜ: 自分の画面の相手は約0.2秒前の位置(Ping 150ms、補間100msの場合) → すると: サーバーは現在位置で判定するため、自分が狙った場所にはもういない → 画面では: 確かに当てたのに外れる。動く対象には偏差撃ちが必要
症状: 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
攻撃者を基準に巻き戻しすぎると、撃たれる側はもう隠れたのに当たります。
なぜ: Pingが高い攻撃者のために、サーバーが大きく巻き戻して判定 → すると: 撃たれる側の画面では、すでに遮蔽物に隠れた後 → 画面では: 「壁の後ろで撃たれた」、Pingが高い人が有利
症状: 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発
それぞれが自分の結果を決めると、自分の画面は快適ですが、ほかの人の画面と結果が食い違い、チートにも弱くなります。
なぜ: 位置・命中をクライアントが決め、サーバーは中継するだけ → すると: 2人が互いに自分が先に当てたと主張し、サーバーは検証できない → 画面では: 相手がワープ・壁抜け、「自分は当てたのに当たっていない」
症状: ワープ, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
全員が同じターンを一緒に計算する構造では、1人の入力が遅れると全員が待たされます。
なぜ: ターンごとに全プレイヤーの入力がそろわないと計算できない → すると: 1人の入力がジッター・パケットロスで遅れて到着 → 画面では: 全員が同時に一瞬止まり、ひどいと「プレイヤーを待っています」ウィンドウ
症状: フリーズ, カクつき, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
相手の入力を予測して先に見せ、外れたら巻き戻して計算し直します。Pingが大きいほど巻き戻す幅が大きくなります。
なぜ: 相手が入力を変える(予測と違う) → すると: 実際の入力がPingの半分だけ遅れて届き、その分を巻き戻して再計算 → 画面では: 相手の動きが数フレーム飛んだり、急に変わったりする
症状: ワープ · 主担当 ゲーム開発チーム・クライアント開発
サーバーのイベントに発生時刻を付けず、受け取ったらすぐに再生すると、ネットワークのジッターがそのまま演出のタイミングのばらつきになります。
なぜ: 「攻撃開始」「エフェクト再生」のイベントを届いた瞬間に実行 → すると: パケットごとに到着時間が違うため、間隔がばらつく → 画面では: 連続攻撃のモーションが速くなったり遅くなったりし、ボスの攻撃パターンのタイミングが毎回違う
症状: カクつき, 早送り · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
リクエストを次のティックまでためてから処理し、結果もその次のティックで送ると、ティック間隔が2回分加わります。
なぜ: 受け取ったリクエストは次のティックで処理 → すると: 処理結果も次の送信ティックにまとめて送る → 画面では: 回線のPingは低いのに、反応がティック間隔の1.5倍ほど一定に遅れる。10ティックのサーバーなら平均0.15秒、最悪0.2秒
症状: 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発
移動速度・クールタイム・射程をサーバーが厳しくチェックしすぎると、ジッターでまとめて届いた正常な入力まで拒否します。
なぜ: 「1ティックで移動できる距離」「クールタイムの許容誤差0ms」のような厳しい基準 → すると: ジッターで2つのコマンドが1ティックにまとめて届くと、ルール違反と判定 → 画面では: 引き戻し、クールタイムが終わったのにスキルが拒否される
症状: 引き戻し, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発
1人のプレイヤーのPCがサーバーの役割をすると、その人の回線とPC性能が全員の体感を決めます。
なぜ: ホストのPCがサーバーの役割を担う(P2P、リッスンサーバー) → すると: ホストの回線やPCが遅いと全員に波及、ホスト自身はPing 0 → 画面では: ホストだけが有利、ホストが抜けると全員がフリーズ・切断
症状: カクつき, フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
自分の画面で先に見せたヒット・スキルを後からサーバーが認めないと、確かに見た結果がなかったことになります。
なぜ: ヒットエフェクト・スキルモーションをサーバーの確認前に先に再生(先行演出) → すると: サーバーが射程・対象の位置・クールタイム・リソースを改めてチェックして拒否 → 画面では: 血しぶきが出たのにダメージなし、スキルのモーションだけ出て効果なし、クールタイムだけ回る
症状: 不発・ロールバック, 引き戻し · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
「ここへ行け」だけをやり取りして経路は両側でそれぞれ計算すると、計算が少し違うだけで、キャラクターやモンスターが別の経路を進んだ後、元の位置に引き戻されます。
なぜ: クリック移動・モンスターの追跡で目的地だけを送り、経路はクライアントが別途計算 → すると: 地形データの違い、ほかのキャラクターとの衝突、計算順序の違いで、サーバーと別の経路を移動 → 画面では: モンスターが壁をすり抜けて進んだ後にパッと位置が移る、クリックしたキャラクターが滑るように向きを変える
症状: ワープ, 引き戻し · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが位置の更新(スナップショット)を1秒に数回しか送らないと、その分だけ補間バッファを長く取る必要があり、ほかのキャラクターをより遠い過去の姿で見ることになります。
なぜ: 送信量を節約するため、位置の更新を1秒に5〜10回しか送らない → すると: なめらかに描くにはバッファをパケット間隔の2倍(200〜400ms)取る必要があり、短くするとパケットを1つ落としただけで止まる → 画面では: 相手の方向転換が遅れて見え、判定と食い違う。バッファが短いとカクつき、パケットロス時にはワープ
症状: カクつき, ワープ, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ラグ報告で最も判断に迷うのは、一部の人だけ、または片方だけに症状が出るケースです。重い1人がほかの人の目にどう見えるか、その人のせいでほかの人まで重くなるかは、サーバーが入力を処理する方式と同期方式によってまったく変わります。同じPCで起動した2つのクライアントのうち、片方だけNPCが表示されない現象もこの章で扱います。
最近のMMOのほとんどはサーバー権威型の構造です。サーバーがすべての結果を決め、クライアントは受け取った結果を描画します。この構造では、ラグはほとんどの場合重い本人にしか現れません。
しかし、重い1人が全員を重くする構造もあります。共通点は「誰かがその人を待っている」ことです。
| サーバーの入力処理方式 | 重い本人に起きること | ほかの人から見た重い人 | ほかの人自身のゲーム |
|---|---|---|---|
| ティックごとにまとめて処理 固定ティック、受け取った入力を一括で | スキルの結果がPingとティック待ちの分だけ遅れる(入力遅延)。移動検証が厳しいと引き戻し | 一瞬止まってから一度に何歩も進む(早送り・ワープ)。ジッターがなくPingが高いだけならなめらか | 影響なし |
| 到着次第処理 イベント方式、受け取り次第適用・送信 | Ping分の入力遅延。ティックを待たない分だけ速い | 移動が速くなったり遅くなったりする(軽い早送り)。まとめて届いた複数のスキルが一瞬で実行される | 影響なし |
| プレイヤー別の入力バッファ 人ごとにためておき、1ティックに1つずつ | バッファの分だけ確定が遅れる | 比較的なめらか。バッファが空になると一瞬その場で止まる | 影響なし |
| ラグコンペンセーションによる判定 攻撃者が見た時点に巻き戻す | 狙ったとおりに当たる(巻き戻しの上限内で) | 隠れた後でもその人の攻撃が当たる | 理不尽な被弾(波及) |
| ロックステップ・ターン待ち | 入力遅延。入力が遅れるとフリーズ | 全員が止まる | フリーズ。遅れるだけでも入力遅延(全員に波及) |
| ブロッキング送信・同期処理 サーバーがその人を待つ | フリーズの後に早送り | そのサーバースレッドが担当する全員が重くなる | スローモーション・フリーズ(そのスレッドが担当する人たちに波及) |
| 重い人がホスト P2P、リッスンサーバー | 本人はPing 0 | 全員の画面がカクつく | 全員にラグ |
| モンスターの制御を重い人が担当 モンスターの移動計算をクライアントに任せる | 本人の画面のモンスターは正常 | その人が担当するモンスターが一瞬止まってからワープ | そのモンスターと戦う全員(波及) |
同じ人が同じPCでクライアントを2つ起動し、片方だけNPCが表示されないなら、回線はほぼ原因になりません。2つのクライアントは同じルーター、同じ回線を使っているからです。違いは3か所で生まれます。
最も有力な手がかりは3つです。名前表示はあるのにキャラクターモデルだけがないか(サーバーは送ったが描画に失敗)、視界から外れて戻ると表示されるか(出現通知が1つ抜けた)、そして表示されない側のウィンドウを前面に出すと改善するか(バックグラウンドウィンドウの処理制限)。逆に、すでに倒されたモンスターが自分の画面にだけ立っている「ゴースト」は、消滅通知が抜けたものです。
回線が悪い人の入力は、不規則にまとまってサーバーに届きます。サーバーがティックごとに受け取った分だけ適用すると、ほかの人の目にはそのキャラクターが一瞬止まってから一気に何歩も進んで見えます。
なぜ: 回線が重い人の移動コマンドが、あるティックには0個、あるティックには2〜3個ずつ届く → すると: サーバーが受け取ったティックに一度に適用するため、そのキャラクターの位置が階段状に変わる → 画面では: ほかの人の画面でそのキャラクターだけが一瞬止まっては一気にまとめて移動。ほかは問題なし
症状: 早送り, ワープ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 外部・外部
パケットが届くたびにすぐ処理して通知するサーバーでは、回線が重い人のまとまって届いた行動が立て続けに即実行されます。
なぜ: 回線が重い人のスキル・移動のリクエストがまとまって届く → すると: サーバーが受け取った瞬間に順番に実行し、すぐに全員へ通知 → 画面では: ほかの人の目には、その人がスキルを一瞬で何個も使ったり、早送りのように動いたりする
症状: 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバーが人ごとに入力を少しためておき、1ティックに1つずつ取り出して使うと、ほかの人の目にはなめらかですが、本人の行動がサーバーで確定するタイミングはその分遅れます。
なぜ: サーバーが回線の重い人の入力をバッファにため、1ティックに1つずつ適用 → すると: バッファが小さいと頻繁に空になり、そのキャラクターがその場に止まるか、サーバーが最後の入力から推測して動かす。大きいと本人の入力の確定が遅れる → 画面では: 小さいとほかの人の目には一瞬止まって見え、大きいと本人のスキルの結果が遅れて出る(入力遅延)
症状: カクつき, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ジッターが大きい回線を使う人は入力がまとまって届くため、サーバーの速度・クールタイムのチェックに頻繁に引っかかります。
なぜ: 特定の通信事業者・地域の回線のジッターが夜に大きくなる → すると: まとまって届いた正常な入力を、サーバーが速度超過・クールタイム違反と判断 → 画面では: その通信事業者のユーザーだけ引き戻し、スキル拒否、ひどいとサーバーから追い出されて切断
症状: 引き戻し, 不発・ロールバック, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
全員が決まった瞬間に一緒に反応しなければならないレイドのギミックでは、回線が重い1人の遅れた反応がパーティ全体の失敗になります。
なぜ: 「全員同時に散開」「1人がボタンを押す」のような全員で対処するギミック → すると: 回線が重い人は予兆を見るのが遅れ、入力も遅れて届く → 画面では: その1人のせいで全滅、ほかのパーティメンバーは「ラグい人のせい」と感じる
症状: 不発・ロールバック, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
サーバー負荷を減らすため、モンスターの移動計算を近くのプレイヤー1人のクライアントに任せるゲームがあります。その人の回線が悪いと、そのモンスターが全員の画面でおかしな動きをします。
なぜ: サーバーがモンスターの移動計算を、最も近い(または先に来た)プレイヤーのクライアントに任せる → すると: 任された人の結果報告が遅れたり、まとまったりしてサーバーに届く → 画面では: そのモンスターだけが周囲全員の画面で一瞬止まってはワープ。任された本人の画面では問題なし
症状: ワープ, カクつき, 早送り · 主担当 ゲーム開発チーム・サーバー開発
アイテム・郵便が数千個たまっていたり、フレンド・ブロックリストやバフが極端に多かったりするキャラクターは、接続時・保存時・周囲への通知で扱う量がほかの人の数倍になります。回線に関係なく、そのキャラクターでだけ重くなります。
なぜ: 長く育てたキャラクターやイベント報酬で、インベントリ・郵便受けに数千個たまる → すると: 接続・エリア移動・保存のたびにその分DBを読み書きし、周囲に送る装備・バフの情報も大きい → 画面では: そのキャラクターだけ入場時のロードが長く、インベントリ・郵便を開くときに一瞬止まる。保存をゲームスレッドで待つサーバーなら、周囲の人まで一時的に止まる
症状: 接続不可・無限ロード, 入力遅延, フリーズ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
2つのキャラクターが別のチャンネルやインスタンスにいたり、クエストの進行度によって見えるNPCが変わる別の「フェーズ」にいたりすると、互いに違う世界を見ることになります。
なぜ: 2つ目のキャラクターが別のチャンネルに割り当てられるか、クエストの段階が違う → すると: サーバーがそのキャラクターにはそのNPCを送らない(正常) → 画面では: 片方にだけNPCがいない。バグのように見えるが設計どおり
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゾーンに入るとすぐにサーバーが周囲のNPCの出現通知を送りますが、クライアントがまだマップを読み込んでいる最中なので、その通知を破棄してしまいます。
なぜ: サーバーが入場処理の直後に周囲のオブジェクトの出現通知を送信 → すると: クライアントはロード中でメッセージハンドラーがまだないため、通知を破棄 → 画面では: サーバーは送信済みとして扱い、再送しない。視界から外れて戻ってくるまでNPCが表示されない
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
キャラクターが視界グリッドに登録される瞬間と、NPCがグリッドのセルを移る瞬間が重なると、そのNPCの出現通知が漏れることがあります。
なぜ: 入場・チャンネル移動・テレポートの処理とNPCの移動が同じ瞬間に重なる → すると: 「新たに見えるようになったオブジェクト」の計算からそのNPCが漏れる → 画面では: 特定のNPC数体だけが表示されないか、すでに去ったNPCが残っている
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・サーバー開発
サーバーが「前回から変わったものだけ」を送る方式では、最初に1回送る全体の情報(基準)を失うと、その後の差分を適用できません。
なぜ: オブジェクトの全体情報(基準)のパケットが失われるか、処理前に破棄される → すると: クライアントはその後の差分を適用する対象がないため無視 → 画面では: そのオブジェクトが表示されないか、かなり後で突然現れる
症状: 表示されない・ゴースト, ワープ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
逆に「消えた」という通知を取りこぼすと、すでに死んだか去ったNPC・プレイヤーが自分の画面にだけ残ります。
なぜ: 死亡・退出・視界外への移動の通知が失われるか、順序が入れ替わる → すると: クライアントはそのオブジェクトがまだいると判断 → 画面では: 叩いても反応しないモンスター、すでに抜けたプレイヤーが立っている
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
ゾーンに入った瞬間、サーバーは周囲の数十〜数百個のオブジェクトの出現情報を一気に送ります。これを非信頼(unreliable)チャネルで送ったり、ロード中でソケットを読めない間に受信バッファがあふれたりすると、一部が消えて二度と届きません。
なぜ: 入場直後に出現情報が短時間に集中して届く → すると: ロード中のクライアントがソケットを読むのが遅れてOSの受信バッファがあふれるか、大きなUDPパケットがフラグメント化され、フラグメントを1つ失っただけで丸ごと消える。非信頼チャネルなら再送もされない → 画面では: ロードが遅い側のクライアントでだけNPCが数体抜ける。視界から外れて戻ると見える
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
倒されたNPCが再び出現するときにサーバーが同じオブジェクトIDを使い回すと、その間に消滅通知を取りこぼしたクライアントは、新しいNPCを古いNPCと誤認します。
なぜ: NPCが倒され、同じオブジェクトIDで再出現 → すると: 消滅通知を取りこぼしたクライアントは「すでに知っているオブジェクト」として出現通知を無視するか、死亡状態のまま残す → 画面では: 片方の画面にだけNPCがいないか倒れたまま見える、別のNPCの姿で見えることもある
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
クライアントが決まったローカルポートを使うように作られていると、同じPCの2つ目のクライアントはそのポートを使えないか、1つ目とパケットを分け合って受け取ることになります。
なぜ: 2つのクライアントが同じローカルUDPポートを開こうとする(再利用オプションで無理に共有) → すると: OSが届いたパケットを片方のソケットにだけ渡すか、どちらが受け取るかを保証しない。ルーターとサーバーも2つのクライアントを同じアドレスとみなす → 画面では: 片方はワールドのパケットを受け取れず、NPC・ほかのプレイヤーが表示されないか切断される
症状: 表示されない・ゴースト, 切断, 接続不可・無限ロード · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
サーバーや中継サーバーが接続をIPや端末IDで区別していると、同じPC(同じグローバルIP)の2つのクライアントを1人として認識します。
なぜ: セッションテーブルをIP、またはIP+端末IDで作っている → すると: 2つ目のクライアントの情報が1つ目のセッションに上書きされるか混ざる → 画面では: 片方はNPCが表示されず、もう片方は切断されるかほかの人の情報を受け取る
症状: 表示されない・ゴースト, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
セキュリティモジュールやサーバーのポリシーが1台のPCでの複数クライアントを制限していると、2つ目のクライアントは起動・接続ができないか、先に起動した側が切断されます。一部のゲームは追加のクライアントの機能だけを制限します。
なぜ: セキュリティモジュールが多重起動を検知、またはサーバーが同じ端末からの追加接続を制限 → すると: 2つ目の起動・接続を拒否するか、片方を切断。まれに追加のクライアントの一部の機能だけを遮断 → 画面では: 接続不可か片方の切断。機能だけを制限するゲームでは、片方だけNPC・ショップが表示されない
症状: 接続不可・無限ロード, 表示されない・ゴースト, 切断 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
バックグラウンドウィンドウのクライアントでは、ゲーム・エンジン・OSがフレームと処理を減らします。受け取ったパケットを時間内に処理できず、詰まったりあふれたりします。
なぜ: ゲームのオプションやグラフィックスドライバーのバックグラウンドのフレーム制限(例:NVIDIAドライバーでは毎秒20〜200の間で指定)、省電力、エンジンのバックグラウンド停止設定。OSも前面のウィンドウ(フォアグラウンド)にCPU・GPUを優先的に割り当てる → すると: フレームごとに処理するパケット数が減ってキューがたまり、受信バッファがあふれると破棄される → 画面では: ウィンドウを前面に出すとまとめて現れるか、一部のNPCが最後まで表示されない
症状: 表示されない・ゴースト, 早送り, 切断 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
2つのクライアントが同じキャッシュフォルダーに同時に書き込んだりファイルをロックしたりすると、片方がNPCのモデル・テクスチャを読み込めなくなります。
なぜ: 2つのクライアントが同じインストールフォルダーのキャッシュ・アップデートファイルに同時に書き込む → すると: ファイルロックの失敗や、書きかけのファイルを読んでロードに失敗 → 画面では: ネームプレートはあるのにキャラクターモデルがない、または透明なNPC
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・クライアント開発
2つのクライアントがビデオメモリを分け合うと、新たに必要なモデル・テクスチャを載せる場所がなく、一部が描画されません。
なぜ: 2つのクライアントがVRAM・RAMを分け合う。OSはバックグラウンドウィンドウのビデオメモリの割り当てを先に減らすこともある → すると: エンジンが新しいモデル・テクスチャを載せられないか、下ろしては載せ直すことを繰り返す → 画面では: NPCが遅れて現れる、ぼやける、表示されない、カクつき
症状: 表示されない・ゴースト, カクつき · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
表示人数の制限、NPCのネームプレート・モデルの非表示、低スペックモードなどのオプションが2つのクライアントで違うと、見えるものが変わります。
なぜ: 片方のクライアントだけ「周囲のキャラクター表示数の制限」や低スペックモード → すると: 遠くにいるか優先度の低いNPCを描画しない(正常) → 画面では: 片方にだけNPCがいない
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・クライアント開発
2つ目のクライアントが別のインストール版だったりアップデートが済んでいなかったりすると、サーバーが送った新しいNPCのIDを知らないため、黙って無視します。
なぜ: 別フォルダーのインストール版、またはアップデート中に起動したクライアント → すると: 知らないNPC ID・モデルIDを受け取ると読み飛ばす → 画面では: 新しく追加されたNPCだけが片方で表示されない
症状: 表示されない・ゴースト · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
サーバーが接続ごとに送る量に上限を設けて近いものから送ると、上限が低く設定された側は、遠くにいるNPCを遅れて受け取るか、受け取れません。
なぜ: 人の多い場所で、サーバーが接続ごとの送信量の上限内で重要度順に送信 → すると: 帯域幅の推定が低く出た接続(例:バックグラウンドウィンドウで受信確認が遅れている側)は、後ろのほうのオブジェクトを後回しにし続ける → 画面では: 遠くにいるNPCが片方でだけ遅れて見えるか、表示されない
症状: 表示されない・ゴースト, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
クライアントが推定したサーバー時刻がずれていると、届いたばかりのオブジェクト情報を「まだ未来」として保留したり、「古すぎる」として破棄したりします。
なぜ: 片方のクライアントのサーバー時刻の推定が大きくずれる(ロード中の測定、省電力からの復帰) → すると: 補間の基準時刻とオブジェクト情報の時刻が合わない → 画面では: オブジェクトが遅れて現れるか、止まったまま見える
症状: 表示されない・ゴースト, カクつき · 主担当 ゲーム開発チーム・クライアント開発
サーバーのメトリクスで「TCP再送(Retransmission)」が増えると、ラグ報告も一緒に増えることがよくあります。再送は「パケットが消えた」、または「消えたと誤って判断した」というシグナルです。原因はWi-Fiからサーバーのネットワークカードまで、経路のどこにでもあります。ゲームのように小さなパケットをまばらに送る接続では、パケットを1つ失っただけで数百msのフリーズにつながります。この章では、再送の根本原因、原因の探し方、解決の方向性をまとめます。
| 種類 | いつ起きるか | 復旧までの時間 | ゲームでの見え方 |
|---|---|---|---|
| 高速再送 Fast retransmit | 後続のパケットが先に届き、受信側が「途中が抜けた」(重複ACK・SACK)と知らせたとき | 往復時間+後続のパケット3つが届くまでの時間 | 一瞬止まる。パケットの間隔が短いほど速い |
| RACK・TLP 時間ベースのロス判定、末尾パケットの再送 | 後から送ったパケットが届いたのに、前のものが一定時間届かないとき。しばらくACKがないときは、末尾のパケットをもう一度送る | 後ろのパケットの確認が来ればすぐ(RACK。順序が入れ替わっただけの可能性があるので、往復時間の1/4ほど余分に待つ)。後ろのパケットがなければ往復時間の約2倍(TLP)、ACK待ちのパケットが1つだけなら遅延ACKを考慮して200ms余分に待つ | thin streamでも比較的短く一瞬止まる程度。最新のLinuxのデフォルト |
| RTO再送 Retransmission timeout | 何のシグナルもないまま待ち時間が満了したとき | 往復時間+最低200ms、失敗するたびに2倍 | 数百ms〜数秒のフリーズの後に早送り、長引くと切断 |
| SYN再送 | 接続要求そのものが消えたとき(接続待ちキュー(backlog)のあふれ、ファイアウォールによる遮断) | 1秒、2秒、4秒、8秒 …(Linux 6.5以降は5回まで1秒間隔で再送した後に倍々、以前のWindowsは3秒から) | 接続ボタンを押してから1秒、3秒のように秒単位できっちり遅れ、失敗が続くと接続不可・無限ロード |
| 不要な再送 Spurious retransmission | 失われていないのに、遅れて届いたり順序が入れ替わったりしたため、失われたと判断して再送する | 復旧するものはない。その代わり送信量だけが減る(LinuxはDSACK(受信側の「もう受け取った」という通知)やタイムスタンプで検知すると元に戻すこともある) | 回線の浪費、大容量転送の速度低下。メトリクス上は再送率だけが高い |
| ゼロウィンドウプローブ 再送と紛らわしいもの | 受信側のバッファが満杯で「しばらく送らないで」という状態のときに、確認用に送るパケット | 受信側が読み出しを始めるまで | フリーズ。回線は正常で、受信側のプログラムが時間内に読み出せていない |
再送率は「送ったパケットのうち再送した割合」です。起動後にたまった累積値は平常時の値に埋もれるので、1分のような一定の間隔で増えた量から計算します。公認の基準はありませんが、サーバー全体の平均についての大まかな目安は、0.1%未満なら健全、0.1〜1%なら一部のユーザーがときどき一瞬止まる、1%を超えると多くのユーザーが体感、3%を超えると深刻です。モバイルや海外のユーザーが多いゲームは、平常時の値が高めに出ます。そのため、1つの数字で判断するよりも、平常時の何倍に増えたかもあわせて確認します。平均は少数の悪い回線に引っ張られるので、地域・通信事業者・サーバー・時間帯別に分けて見るのが原因を見つける近道です。接続を途中で受けてサーバーへ新たにつなぎ直す機器(プロキシ、一部のロードバランサー・ゲートウェイ)があると、ゲームサーバーのメトリクスにはその機器とサーバーの間の区間しか現れません。ユーザー側の再送はその機器で確認します。
| 確認場所 | 見る項目 | わかること |
|---|---|---|
| サーバー全体(Linux) | nstatを1分間隔で2回実行したときの増分:TcpRetransSegs ÷ TcpOutSegs、およびTcpExt系のTCPTimeouts、TCPLossProbes・TCPLossProbeRecovery、TCPLostRetransmit、TCPSpuriousRTOs、TCPDSACKRecv、TCPSynRetrans | 再送率、RTOまで行った回数、TLPを送った回数とそのうち実際のロスを埋めた回数、再送したものまで再び失った回数、接続要求の再送。DSACK・Spuriousが多ければ「失われていないのに再送」。LinuxのOutSegsには再送分が含まれないので、厳密な割合はRetransSegs ÷ (OutSegs + RetransSegs)ですが、1%前後では差は小さいです |
| 接続ごと(Linux) | ss -tiのretrans(現在復旧中/累積)、rto、backoff、rtt、cwnd、lost、reordering、bytes_retrans | 特定のユーザー・地域だけ再送が多いか、RTOがどれだけ伸びているか(backoffはRTOが連続して2倍になった回数)。bytes_retrans ÷ bytes_sentがその接続の再送率 |
| 再送1件ずつ(Linux) | eBPFツールtcpretrans(bcc)。-cは接続ごとの集計、-lはTLPを含む | 再送が起きるたびに、相手のIP・ポート・接続状態を1行ずつ表示します。パケットキャプチャなしで手軽に、どのユーザーのIP帯・サーバーに集中しているかを確認 |
| サーバーのネットワークカード | ip -s -s linkのdropped・missed・crc、ethtool -Sのrx_missed_errors・rx_no_buffer_count・rx_crc_errorsなど(名前はドライバーごとに異なり、mlx5はrx_out_of_buffer・rx_discards_phy)、/proc/net/softnet_statの2列目(dropped)・3列目(time_squeeze) | サーバーのネットワークカードが受け取った直後に破棄したのか(リングバッファ・CPU)、ケーブルや光モジュールの不良(CRC)なのか。softnet_statはCPUごとに1行で、16進数です。time_squeezeが増え続けるなら、受信処理を担当するコアが時間内に処理を終えられていない |
| クラウドネットワーク | AWS ENAはethtool -Sのbw_in_allowance_exceeded、bw_out_allowance_exceeded、pps_allowance_exceeded、conntrack_allowance_exceeded、linklocal_allowance_exceeded。CloudWatchのデフォルトの画面にはないので、CloudWatchエージェントで別途収集します | インスタンスの上限で黙って破棄したか。値が増えていれば上限超過です。ほかのクラウドにも、VMサイズごとの帯域幅・接続数の上限があります |
| スイッチ・ルーター・ファイアウォール | ポートのCRC・入力エラー、出力ドロップ、ポリサー超過、セッションテーブル使用量、ドロップログ | データセンター機器の区間で破棄したか。5分平均の使用率が低いのに出力ドロップが増えるなら、マイクロバースト(ごく短い瞬間のトラフィック集中) |
| 経路 | mtr・pathpingで見る、最後まで続くロス。数百回以上送らないと1%前後のロスは見えません。ゲームと同じTCPポートに送る(mtr -T -P PORT)とより正確です | 何番目の区間からロスが始まるか。途中の1区間だけがロスに見えて後ろが正常なら、その機器が測定用の応答(ICMP)をレート制限しているだけです。行きと帰りの経路が異なることがあるので、サーバー側からユーザー側へも測定します |
| パケットキャプチャ(両端) | Wiresharkのフィルターtcp.analysis.retransmission、同じtcp.analysis.系のfast_retransmission、spurious_retransmission、duplicate_ack、lost_segment、zero_window | 元のパケットが送信側のキャプチャにはあって受信側になければ、その間で失われたもの。受信側にもあれば、不要な再送か、ACKが戻る途中で遅れたか消えたもの。受信サーバーのリングバッファで破棄されたパケットもキャプチャでは「間で失われた」ように見えるので、ネットワークカードのカウンターとあわせて確認します |
| Windowsサーバー | パフォーマンスモニターのTCPv4\Segments Retransmitted/sec ÷ Segments Sent/sec、Network Interface\Packets Received Discarded、netsh int tcp show global、pktmon(Windows 10 1809・Windows Server 2019以降に内蔵) | 再送率の推移、ネットワークカードが受け取った直後に破棄したか、TCP設定、Windows内部のどこで破棄したか |
確認の順序:インフラチームと一緒に確認するときは、次の順序が早道です。
報告に時刻(秒単位)、ユーザーの通信事業者・地域、接続先サーバー、症状名があれば、インフラチームはすぐにこの手順で調べられます。
1. 失わないようにする(根本的な解決)
2. 速く復旧させる
tcp_thin_linear_timeouts、Linux 6.15以降はTCP_RTO_MAX_MSでRTOの上限を下げるTCP_NODELAYを有効にしておく(Nagleアルゴリズムが新しいパケットを送らずにためておくと、RACKが使う後続のパケットがなくなる)ip route … rto_min)TCP_USER_TIMEOUTとゲームのハートビートで、死んだ接続を早く切って再接続3. 再送の影響を受けにくくする(構造)
TCP_NOTSENT_LOWATなど)。長いフリーズの後の早送りが短くなる再送の復旧に関わる設定のほとんどはOS(カーネル)の設定で、ゲームの接続にだけ個別に有効にできるソケットオプションはわずかです。名前のせいでよく誤解されるTCP_NODELAYは、復旧を速くする設定ではありません。ただし、有効にしないと(Nagleアルゴリズムを使うと)、復旧中に新しいパケットがさらに遅れます。以下はLinuxの場合で、Windowsは名前と対応範囲が異なります。
| 設定 | 設定場所 | 何を変えるか | 注意 |
|---|---|---|---|
TCP_NODELAY | ソケットオプション | Nagleアルゴリズムを無効化。小さなメッセージをためずにすぐ送る | パケットロスがなくても生じる40〜200msの待ちをなくす。再送タイマー(RTO)自体は変わらない。ただし、Nagleアルゴリズムが有効だと、復旧を待つ間に新しいパケットまで足止めされて復旧後にさらに1往復待つ。高速再送・RACKが頼る後続のパケットもなくなるので、RTOまで行きやすい。ゲームでは有効にするのが普通 |
net.ipv4.tcp_recovery (RACK) | カーネル設定 | 時間ベースのロス判定。順序の入れ替わりに強く、thin streamも速く復旧 | デフォルト値1(有効)。Linux 4.4で導入され、4.18ごろに現在の形になった。6.17からはRACKが唯一のロス判定方式なので、0にしても効果がない。SACKのない接続では動作しない |
net.ipv4.tcp_early_retrans (TLP) | カーネル設定 | しばらく(往復時間の約2倍)ACKがなければ末尾のパケットをもう一度送り、末尾パケットのロス(tail loss)を早く発見 | デフォルト値3(有効)、0なら無効。SACKがないと動作しない。ACK待ちのパケット(in-flight)が1つだけなら200ms余分に待つので、RTOと大差なくなる |
net.ipv4.tcp_sack, tcp_dsack, tcp_timestamps | カーネル設定 | 選択的ACK(SACK、途中の抜けの通知)、重複受信の通知(DSACK)、往復時間の測定(タイムスタンプ) | デフォルトはすべて有効。2019年のSACKのセキュリティ問題のときに無効にしたまま残っているサーバーがある。SACKが無効だとRACK・TLPも動作しない |
net.ipv4.tcp_thin_linear_timeouts / TCP_THIN_LINEAR_TIMEOUTS | カーネル設定 / ソケットオプション | ACK待ちのパケット(in-flight)が4つ未満の接続では、最初の6回までRTOを倍々に増やさない | デフォルトは無効。ソケットオプションでゲームの接続にだけ有効にできる。最初のRTOは短くならない |
TCP_RTO_MAX_MS / net.ipv4.tcp_rto_max_ms | ソケットオプション / カーネル設定(Linux 6.15以降) | 倍々に増えるRTOの上限(デフォルト120秒)を下げる。最小1秒 | 連続したパケットロスの後に、RTOが数十秒まで大きくならないようにする。死んだ接続の判定も一緒に早くなる |
net.ipv4.tcp_mtu_probing | カーネル設定 | 大きなパケットが消え続けるとサイズを小さくし、MTUブラックホールを通過 | デフォルト0(無効)。1 = 再送が3秒ほど続いてブラックホールが疑われるときだけ小さくする(その間はフリーズ)。2 = 最初から1,024バイトで始めて少しずつ大きくしてみる |
ip route … rto_min | 経路設定 | その経路のRTO最小値(デフォルト200ms)を下げる | サーバー同士の内部ネットワークに限る。インターネット区間で下げると不要な再送が増える。Linux 6.11以降のnet.ipv4.tcp_rto_min_usはサーバー全体の値なので、インターネット側の接続まで一緒に変わる。6.15以降はソケットオプションTCP_RTO_MIN_USで内部の接続だけ下げられる |
TCP_USER_TIMEOUT | ソケットオプション | 再送が続くときに接続を諦めるまでの時間 | 復旧を速くはしない。死んだ接続を早く切って再接続させる。設定しないと、Linuxは再送を15回前後、約15分続けてからようやく切断する(tcp_retries2) |
SO_KEEPALIVE + TCP_KEEPIDLEなど | ソケットオプション | アイドル接続が生きているかを確認 | 再送とは別物。NAT・LBのマッピング維持と、死んだ接続の検知用 |
fqキュー + SO_MAX_PACING_RATE、BBR | キュー設定 / ソケットオプション / カーネル設定 | パケットを均等に分けて送り、バースト(一度にまとめて送ること)によるパケットロスを減らす | パケットロスを「予防」するためのもの。復旧速度とは別物 |
Wi-Fiとモバイル回線は、無線区間で何度か再送し、それでも届かなければパケットを破棄します。破棄されたパケットは、TCPがかなり後になってから送り直します。
なぜ: 電波が弱いか干渉が強く、無線区間での送信が連続して失敗 → すると: 無線機器の再試行上限(通常は数回〜十数回)を超えるとパケットを破棄 → 画面では: TCPの再送を待つ間止まり、後続のパケットは受信バッファで待たされた後に早送り
症状: フリーズ, 早送り, ワープ · 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ルーター、通信事業者どうしの接続区間、データセンターの回線のように、最も細い箇所のキューが満杯になると、新しく届くパケットを破棄します。
なぜ: 動画・ダウンロード・他のユーザーのトラフィックでボトルネック区間が満杯 → すると: キューが満杯の間、新しく到着するパケットが続けて破棄される(tail drop)。破棄されなかったパケットも満杯のキューの末尾で待たされる → 画面では: 複数のパケットが一度に消え、長く止まった後に早送り、夜の時間帯に多い
症状: フリーズ, 早送り, 引き戻し · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部, ゲーム開発チーム・クライアント開発
サーバーがティックごとに数千人分の更新を一瞬でまとめて送ると、スイッチの小さなバッファやクラウドの瞬間的な上限が1ms足らずであふれ、一部が破棄されます。
なぜ: ティックの開始時に、全員に送るパケットを一度に送信 → すると: 複数のサーバーのトラフィックが集まるスイッチポートのバッファ(ポートあたり数百KB〜数MB)やクラウドインスタンスの上限が瞬間的にあふれる(平均利用率は低い) → 画面では: 複数の人が同時にワープしたり一瞬止まったりする、平均値のメトリクスでは原因が見えない
症状: ワープ, フリーズ, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ
通信事業者の料金プラン、クラウドインスタンスの上限、DDoS対策機器は、決められた速度を超えるパケットをキューに入れずにすぐ破棄することもあります。
なぜ: 瞬間的な送信量が許容速度・許容バーストを超える → すると: 超えたパケットをキューに入れずにすぐ破棄(ポリシング) → 画面では: バーストが大きい瞬間ごとに複数のパケットが消え、止まった後に早送り、平均速度は上限を下回って見える
症状: フリーズ, 早送り, ワープ · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
ケーブルの損傷、ほこりの付いた光コネクター、寿命を迎えた光モジュールはビットエラーを起こし、壊れたパケットは機器が黙って破棄します。
なぜ: ケーブル・光モジュール・コネクターの不良でビットが反転 → すると: チェックサム(CRC)が合わないパケットを機器が破棄 → 画面では: その経路を通る人だけが継続的に一瞬止まっては早送り、時間帯とは無関係
症状: フリーズ, 早送り, ワープ · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, 外部・外部
片側はオートネゴシエーション、もう片側は速度・デュプレックスを固定にしておくと、片側が半二重で動作し、負荷がかかるたびに衝突(コリジョン)でパケットを失います。
なぜ: 機器の片側だけ速度・デュプレックスを固定設定 → すると: 片側は全二重、もう片側は半二重で動作し、コリジョン・レイトコリジョンが発生 → 画面では: 普段は問題ないが、トラフィックが増えるとその機器を通る人全員が止まっては早送り
症状: フリーズ, 早送り · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
パケットはサーバーまで届いたのに、NICのリングバッファ(到着したパケットを一時的に入れておくバッファ)があふれたり、カーネルで受信処理を担うコアが飽和したりして破棄されます。
なぜ: 接続数の急増・1つのコアに集中した割り込み・仮想マシンのCPUスチール・仮想スイッチの過負荷 → すると: リングバッファ(rx_missed_errorsなど、名前はドライバーによって異なる)やカーネルの受信キュー(softnet dropped)で破棄 → 画面では: 人が集中すると、サーバー全体で同時に入力の反映が遅れ、一瞬止まる
症状: 入力遅延, フリーズ, 早送り, ワープ · 主担当 インフラチーム・サーバーインフラ
ファイアウォールやLinuxの接続追跡(conntrack、通過する接続をテーブルに記録する機能)は、テーブルが満杯になったり、接続の状態が合わないと判断したりすると、パケットを破棄します。
なぜ: 接続追跡テーブルが満杯(table full)、または行きと帰りの経路が異なり、片方向だけがファイアウォールを通る(非対称経路) → すると: ファイアウォールが「知らない接続」や「ウィンドウの範囲から外れたシーケンス番号」のパケットとみなして破棄 → 画面では: テーブルが満杯になると新規接続ができなくなり、経路がずれるとその経路の人だけが再送を繰り返した末に切断
症状: フリーズ, 切断, 接続不可・無限ロード · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ファイアウォール、侵入防止システム(IPS)、DDoS対策機器は、通過するパケットを1つずつ検査します。検査能力を超えた瞬間から、処理しきれなかったパケットを破棄します。
なぜ: ピーク時間帯・イベントで小さなゲームパケットが毎秒数十万個以上集中、または検査ルールが重い → すると: 機器のCPU・秒間パケット数が上限に達し、機器で破棄。誤検知なら正常なパケットも遮断 → 画面では: その機器の後ろにあるサーバー全体で同時にフリーズ・ワープ、人が集中したときだけひどくなる
症状: フリーズ, 早送り, ワープ, 切断 · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
途中の区間が受け取れるサイズが小さくなったのに「大きすぎる」という通知(ICMP)が遮断されると、大きなパケットは何度送り直しても消え続けます。
なぜ: VPN・トンネル区間で最大サイズが小さくなり、サイズ超過の通知はファイアウォールで遮断 → すると: 送信側は理由がわからないまま同じ大きなパケットを再送し続け、RTOは2倍ずつ増加 → 画面では: 普段は問題ないが、インベントリ・人の多い場所・入場時のロードのように大きなデータがやり取りされる瞬間に、後続の小さなパケットまですべて止まり、最終的に切断や無限ロード
症状: フリーズ, 切断, 接続不可・無限ロード · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
アイドル接続のマッピング(この接続をどこに転送するかを記録したエントリ)を中間機器が消すと、次に送るパケットは転送されません。再送だけを繰り返した末に切断されるか、機器が接続拒否(RST)を返してすぐに切断されます。
なぜ: しばらくパケットのやり取りがない接続(離席、ロビー) → すると: ルーターのNAT・通信事業者のCGNAT・ファイアウォール・ロードバランサー・クラウドのセキュリティグループがアイドル状態のマッピングを削除 → 画面では: 再び動いた瞬間に再送が続いた末に切断、またはすぐに切断
症状: 切断, フリーズ · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ, インフラチーム・サーバーインフラ
インターネットの経路が切り替わる数秒の間、または複数のECMP経路のうち不良な経路に割り当てられた接続で、パケットが消えます。
なぜ: BGPの経路再計算、または複数の経路(ECMP・LAG)のうち1つの経路で機器・回線が不良 → すると: 経路の切り替え中に一時的なパケットロス、またはその経路を通る接続だけに継続的なパケットロス → 画面では: 突然数秒止まった後に早送り、または「再接続すると直る」(別の経路に割り当てられる)
症状: フリーズ, 早送り, ワープ · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
パケットは消えておらず、一時的にとても遅れて届いただけなのに、その遅延がRTOより長いと、送信側はパケットロスと判断して再送します。
なぜ: バッファブロート、Wi-Fiの省電力、モバイルの無線状態の切り替え、仮想マシンの一時停止で、瞬間的な遅延が数百ms → すると: RTOが先に満了して再送、元のパケットもすぐに到着(受信側は重複して受け取る) → 画面では: フリーズ・早送りは遅延の急上昇そのものが原因。不要な再送は止まる時間をほとんど延ばさず、再送のメトリクスだけを押し上げるため、パケットロスと誤解される
症状: フリーズ, 早送り, 入力遅延 · 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
複数の経路や束ねたリンクを通る間にパケットの順序が入れ替わると、受信側が重複ACKで「抜けたパケットがある」と知らせ、送信側は問題のないパケットを送り直します。
なぜ: パケット単位で経路を振り分ける機器、パケット単位で振り分けて送るLAG(リンクアグリゲーション)、経路が切り替わる瞬間が順序を乱す → すると: 後のパケットが先に到着して重複ACKが3つたまる → 高速再送 → 画面では: まばらにやり取りされるゲームパケットにはほとんど影響なし。人の多い場所での大きな更新やアップデートデータのダウンロードが遅くなり、ときどきカクつく
症状: カクつき, 入力遅延 · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
データは問題なく届いているのに、「受け取った」というACKが満杯の上りキューで遅れたり消えたりすると、送信側はパケットロスと判断して再送します。
なぜ: 家で動画のアップロード・クラウドバックアップにより上り回線が満杯 → すると: ACKがルーターのキューで数百ms遅れるか、あふれて破棄される → 画面では: サーバーが送るゲームパケットはおおむね時間どおりに届く。同じ上りキューにたまった自分の入力が遅れて入力遅延・引き戻し、ときどき不要な再送
症状: 入力遅延, 引き戻し · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
RTOの最小値を下げすぎると少し遅れただけで不要な再送が起き、デフォルト値(200ms)はゲームにとっては長すぎて、1回失うたびに長く止まります。
なぜ: データセンター向けにRTOの最小値を大きく下げた、またはインターネット区間でデフォルト値のまま使用 → すると: 低いと瞬間的な遅延でも再送が殺到、高いとパケットロスのたびに長く待つ → 画面では: デフォルト値ならパケットロス1回で数百ms止まった後に早送り、下げすぎると止まる時間は減るが不要な再送が急増して回線を浪費
症状: フリーズ, 早送り, 入力遅延 · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲームのように小さなパケットをまばらに送ると、「後続のパケット3つ」がそろう前にRTOが先に来ます。大容量の転送と比べて、同じパケットロスでもはるかに長く止まります。
なぜ: パケットの間隔が100ms前後なので、ACK待ちのパケット(in-flight)が数個しかない → すると: 重複ACKが3つそろうには300ms以上かかるため、RTO(Ping + 200ms)が先に発動、連続したパケットロスなら2倍ずつ → 画面では: パケットロス1回で0.3秒前後止まり、送り直したものまで失うと1秒近く止まった後に早送り
症状: フリーズ, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
一部のファイアウォール・高速化装置がTCPオプションを消したり書き換えたりすると、複数のパケットを失ったときに1往復に1つずつしか回復できなくなったり、ウィンドウ(一度に送れる量)が小さくなったりして遅くなります。
なぜ: ファイアウォールの「TCP正規化」、古い高速化装置がSACK・タイムスタンプ・ウィンドウスケールのオプションを除去 → すると: 失ったパケットが複数あると1往復ごとに1つずつ回復、ウィンドウは64KBに制限される → 画面では: パケットロスのたびに止まる時間がずっと長くなり(SACKがないとRACK-TLPも使えない)、解消すると早送り。アップデートデータのダウンロードのような大容量の転送も遅い
症状: フリーズ, 早送り · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
受信側のプログラムがソケットを読むのが間に合わず、バッファが満杯になると、送信側は送信を止めてゼロウィンドウプローブだけを送ります。回線の問題ではありません。
なぜ: クライアントのフレームが止まる、サーバーのスレッドがブロックされるなどでソケットを読めない → すると: 受信ウィンドウが0になり、送信側は送信を止めてプローブだけを送る(間隔がだんだん延びる) → 画面では: 止まった後に早送り。パケットキャプチャに「ZeroWindow」が見え、パケットロスはない
症状: フリーズ, 早送り · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・サーバーインフラ
接続要求が接続待ちキュー(backlog)のあふれやファイアウォールの遮断で消えると、クライアントOSは1秒後から間隔を延ばしながら送り直します。
なぜ: メンテ明けの接続の殺到でサーバーの接続待ちキューがあふれる、またはファイアウォール・DDoS対策がSYNを破棄 → すると: クライアントOSが1秒後から決まった間隔でSYNを再送(以前のLinuxは1秒 → 2秒 → 4秒) → 画面では: 接続ボタンを押してから1秒、3秒のようにきりのいい秒数だけ遅れ、失敗が続くと接続不可・無限ロード
症状: 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ, ゲーム開発チーム・クライアント開発
同じラグでも、直す担当は違います。クライアント・サーバーのコードと同期設計はゲーム開発チームが、回線・ネットワーク機器・サーバー機器・DBサーバーはインフラチームが担当します。ユーザーのPCや家庭内ネットワーク、通信事業者の区間、クラウド事業者側の問題は、どちらのチームも直接は直せないため、案内や依頼で対応するか、迂回します。すべての原因カードに主担当と副担当を表示しています。カードの「数値の目安・確認方法・チーム別の対応」を開くと、チームごとの対応が分けて書かれています。
| 担当 | 担当範囲 | 主な解決手段 |
|---|---|---|
| ゲーム開発チームクライアント | ゲームクライアントのコード:フレーム・GC・ロード、補間・外挿・予測、クライアントのネットワーク処理(ハートビート送信・自動再接続を含む) | コード修正、補間バッファ・予測の調整、ロード方式の変更、ハートビート間隔・再接続フロー、クライアントのアップデート |
| ゲーム開発チームサーバー | ゲームサーバーのコード:ティック・スレッド・ロック、同期設計、接続処理(acceptループ・listenの引数)、ハートビートへの応答・切れた接続の後始末、ソケットオプション、クエリ・トランザクション設計 | ロジックの最適化、非同期呼び出し、ティック・エリアの分散、ログイン待機列、セッショントークンによる引き継ぎ、ソケットオプション(TCP_NODELAYなど)、クエリ・インデックス設計、サーバーのアップデート |
| インフラチームネットワーク | 回線とデータセンターのネットワーク機器(スイッチ・ルーター・ファイアウォール・ロードバランサー・DDoS対策)、クラウドのネットワークACL・VPCルーティング・ロードバランサー、通信事業者・ピアリング | 機器の設定・交換、回線・ピアリングの増強、経路変更、通信事業者へのエスカレーション、ロードバランサー・ファイアウォールのアイドルタイムアウト・セッション上限の調整 |
| インフラチームサーバー機器・OS | サーバー機器・クラウドインスタンス(セキュリティグループ・接続追跡を含む)、OS・カーネル設定、NIC、デプロイ・監視環境 | 増設・インスタンス変更、カーネル設定(sysctl:somaxconn・conntrackなど)、セキュリティグループの構成・接続追跡の時間、NICのリングバッファ・割り込みの分散、cron・バックアップの時刻調整 |
| インフラチームDBサーバー | DBサーバー・ストレージ、DBの設定・レプリケーション・バックアップ、キャッシュサーバー | DBの増強、ストレージのIOPS確保、DBパラメータ・レプリケーション設定、バックアップ・チェックポイントの調整 |
| 外部ユーザー・ISP・クラウド | ユーザーのPC・家庭内ネットワーク、通信事業者の区間(自社の契約外)、クラウド事業者 | ユーザーへの案内(有線接続など)、通信事業者・クラウド事業者への依頼、ゲーム側での迂回・緩和 |
太字の数字はその担当が主担当の原因の数、+数字は副担当の原因の数です。マスを押すと、その原因とチームの対応が下に表示されます。
主担当は、根本原因がある場所、またはそれを取り除ける場所です。回線や機器が原因でも、ゲーム開発チームはその間、影響を減らす設計(補間バッファ、入力の重複送信、再接続)でしのぎます。サーバーのコードが原因なら、インフラチームが機器を増やしても一時的に先送りするだけです。よく迷う境界は次のように決めました。
表の「まず」は、その現象に当てはまる原因カードの主担当を数えて決めた、最初に呼ぶ担当です。2つある場合、前にあるのは主担当になっているカードが最も多い担当で、後ろは最初から一緒に呼ぶ担当です。
| 現象 | ゲーム開発チームの対応 | インフラチームの対応 | まず確認するメトリクス |
|---|---|---|---|
| 特定の通信事業者・地域でパケットロス・ジッターが大きい まずインフラチームネットワーク | 適応型の補間バッファ、入力の重ね送り、パケットロスに強いUDP送信、接続ごとのロス・再送の統計から影響を受けている人のIP・ポート・時刻を抽出、移動検証の基準を回線状態に応じて緩和 | ゲームと同じプロトコル・ポートで双方向の経路測定(mtr)、不良経路の除外、通信事業者へのエスカレーション、ピアリング・回線の追加 | 通信事業者別のロス率・ジッター分布、再送率 |
| TCP再送の増加 まずインフラチームネットワークゲーム開発チームサーバー | TCP_NODELAY、1ティック分の送信をティック内で分けて送る、ソケットを遅れずに読み出す(ゼロウィンドウを防ぐ)、ハートビートでマッピングを維持、リアルタイムのパケットはUDPか別の接続で送る、送信バッファに古い位置をためない(TCP_NOTSENT_LOWAT) | ロス箇所の除去(ケーブル・光モジュール・デュプレックス・ポリサー・ファイアウォールの接続追跡・MTU)、MSS調整、サーバーのリングバッファ・割り込みの分散、カーネルの復旧設定(RACK・tcp_mtu_probing) | 再送の増分(nstat)、ゼロウィンドウの回数、NIC・スイッチポートのドロップ・CRCカウンター |
| サーバーのCPU飽和でティック超過 まずゲーム開発チームサーバー | 視界計算・ブロードキャストの最適化、ティックを複数のスレッドに分割、混雑するエリア・チャンネルの分割、ワーカースレッド数をCPUの上限に合わせる、ティック処理時間をメトリクスとして記録 | シングルコア性能(クロック)が高いCPU・インスタンス、コアごとのCPU使用率のアラート、CPUスチール・コンテナのCPUスロットリングの確認、割り込み処理のコアとティックスレッドのコアを分離 | ティック処理時間、コアごとのCPU使用率・steal・スロットリング回数(nr_throttled) |
| DBの応答遅延 まずゲーム開発チームサーバーインフラチームDBサーバー | クエリ・インデックス・トランザクション設計(短く、ロック順序を統一)、ゲームスレッドの外で非同期呼び出し、まとめて取得・キャッシュ、コネクションプールのサイズ・待機タイムアウトの調整 | 遅いクエリ・実行計画・ロック待ちを見つけてゲーム開発チームに共有、チェックポイント・レプリケーション・統計情報更新の設定、ストレージのIOPS、サーバー数 × プールサイズが最大接続数以内かを確認、DBサーバーの増強 | スロークエリログ、ロック待ち、コネクション待ち、レプリケーション遅延、IOPS |
| メンテ明けに接続不可 まずゲーム開発チームサーバー | 接続を受け付けるスレッド(acceptループ)がほかの処理で止まらないようにする、listenのbacklog引数を増やす、ログイン待機列システム、ログインのクエリをまとめる(N+1の解消)、クライアントの再試行間隔を延ばしつつランダムに分散 | カーネルのsomaxconn・SYN Cookie、ファイアウォール・ロードバランサーのセッション上限、サーバーのconntrack・ファイルディスクリプタの上限、DBキャッシュのウォームアップ、イベント前にサーバーを事前に拡張 | ListenOverflows、セッションテーブル・conntrackの使用率、ログインのクエリ数・コネクション待ち |
| 放置していると切断 まずゲーム開発チームクライアント | クライアント:最も短いアイドルタイムアウトの半分以下の間隔でハートビートを送る(1つが遅れたり抜けたりしても、タイムアウト前に次が届くように)、切断されたら自動で再接続。サーバー:ハートビートに応答し、一定時間届かなければ先に接続を片付け、セッショントークンで引き継ぐ。 | 経路上のロードバランサー・ファイアウォールのアイドルタイムアウト(ネットワーク)とクラウドのセキュリティグループの接続追跡時間(サーバー機器・OS)をまとめてゲーム開発チームに共有、自社の機器は必要なら延ばす。ユーザーのルーター・通信事業者のCGNATのタイムアウトは変えられない | 切断された接続のアイドル時間の分布(ある値の付近に集中していれば、そのタイムアウトを持つ機器)、回線の種類(モバイル・有線) |
| 決まった時刻にサーバーが止まる まずゲーム開発チームサーバーインフラチームサーバー機器・OS | 正時のイベント・保存・タイマー・キャッシュ期限切れの時刻をランダムに分散、バッチクエリは細かく分けて少しずつ、停止時間の短いGCを明示的に指定 | cron・バックアップ・ログ圧縮の時刻分散とI/O優先度の引き下げ、DBバックアップはレプリカで取りチェックポイントは均等に、ディスクのバーストクレジットの確認、バックアップ転送速度の制限 | 止まった時刻とジョブのスケジュール(cron・バックアップ・バッチ・チェックポイント)、GCログ |
| DDoS・トラフィックの急増 まずインフラチームネットワーク | ゲームのトラフィックパターン(ポート、パケットサイズ、秒間パケット数)をインフラチームに共有、アカウント・キャラクターごとのリクエスト頻度の制限、異常なパケットの早期遮断 | DDoS対策(スクラビング)とゲームのトラフィックに合わせた防御ルール、サーバーアドレスの秘匿、機器の秒間パケット数の上限、IP単位の制限は通信事業者の共有IP・ネットカフェを考慮 | 秒間パケット数、機器のCPU・ドロップ、地域・通信事業者別の接続失敗率(誤検知の確認) |
| ユーザーのWi-Fi・PCの問題 まず外部ユーザー・ISP・クラウドゲーム開発チームクライアント | ゲーム内のネットワーク状態表示(Ping・ロス)、ジッターに応じて補間バッファの長さを自動調整、ラグが起きたときのログに回線の種類・PCのCPU使用率を記録、有線接続などの案内文 | 直接は直せない。同じ通信事業者・地域に報告が集中したら、回線の問題として分類し直す | 報告にある回線・端末の情報、同じ通信事業者・地域の割合 |
ゲーム開発チーム → インフラチーム
インフラチーム → ゲーム開発チーム
両チーム共通:障害対応の責任者を1人決め、1つのチャンネルに時系列の記録を残し、次の共有時刻を事前に知らせます。主担当がほかのチームに移るときはこの記録も一緒に渡し、同じ確認を繰り返さないようにします。終わったら、同じ記録をもとに該当する原因カードの担当と対応を修正します。
プレイヤーのPCやスマホで動いているゲームプログラムそのものです。ネットワークが完璧でも、ここでフレームが遅れると画面がカクつきます。また、ネットワークが悪いときにそれをどれだけうまく隠せるかも、ここで決まります。
ゲームは1秒に60回ほど同じ処理を繰り返します。入力を読み、受け取ったパケットを処理し、ゲームの状態を1ステップ進め、画面を描きます。このループ1回がフレームで、60FPSなら1フレームに使える時間は16.7msです(30FPSで動くスマホゲームなら33.3ms)。1フレームが遅れるとその分だけ画面が止まり、次のフレームで遅れた分だけ一気に動きます。
ネットワーク面でクライアントがする仕事は「足りない情報を埋めること」です。ほかのプレイヤーの位置はサーバーから飛び飛びに届くため、その間をつないで描く必要があり(補間)、パケットが途切れたら推測して動かす必要があり(外挿)、自分のキャラクターはサーバーの確認を待たずに先に動かして見せます(予測)。これらの技術が失敗したときの見え方が、そのままワープ、引き戻し、カクつきです。
ゲームクライアントは生中継の映像を作る放送局の副調整室です。現場(サーバー)から写真が飛び飛びに届くと、その間を自然につなぎ合わせて映像のように見せます。写真が遅れて届くと、つなぐ写真がなくて画面が止まります。編集室そのものが忙しくても放送は途切れます。
1フレームの計算に普段の数倍の時間がかかり、画面が一瞬止まります。
なぜ: スキルエフェクトの急増、大量スポーン、UI全体の更新が1フレームに集中 → すると: 16.7ms以内に終わらず、50〜300msかかる → 画面では: 画面が一瞬止まり、次のフレームで全員が一気に動く
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・クライアント開発
使い終わったメモリ(ガベージ)を回収する間、ゲーム全体が止まります。一定の間隔でカクつくのが特徴です。
なぜ: 毎フレーム、一時的な文字列・配列・リストを作っては捨てる → すると: ガベージがたまると、GCがメインスレッドを止めて回収 → 画面では: 数秒〜数十秒ごとに規則的にカクつく
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・クライアント開発
初めて見るエリア・モンスター・エフェクトを描画する直前に、ファイルの読み込みやシェーダーの生成を待って止まります。
なぜ: 新しいエリアへの進入、初めて見るスキル・装備・モンスターの登場 → すると: メインスレッドがファイルの読み込みとシェーダーコンパイルを待つ → 画面では: 初回だけ0.1〜1秒止まり、2回目以降は問題ない
症状: フリーズ, カクつき · 主担当 ゲーム開発チーム・クライアント開発
HDDのような遅いストレージでは、オープンワールドのテクスチャ・モデルを読み込む速度が移動に追いつかず、オブジェクトの表示が遅れたり、ゲームが読み込みを待ってカクついたりします。
なぜ: 乗り物・テレポートで高速に移動したり、人が多い場所に入ったりして、新しいテクスチャ・モデルが一気に必要になる → すると: HDDのような遅いストレージが必要な速度で読み込めず読み込み要求がたまり、一部のロードはメインスレッドが完了まで待つ → 画面では: テクスチャがしばらくぼやけ、建物・キャラクターの表示が遅れ、読み込みを待つ瞬間にカクつき・フリーズ
症状: 表示されない・ゴースト, カクつき, フリーズ · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
攻城戦やワールドボスのように数百人が1つの画面に入ると、描画のコストそのものが処理しきれなくなります。
なぜ: 1つの画面に数百人とエフェクトが重なる → すると: アニメーション・影・名前表示・エフェクトのコストが人数に比例して増加 → 画面では: FPSが60 → 15に落ち、すべての動きがカクつき、入力も遅れる
症状: カクつき, 入力遅延 · 主担当 ゲーム開発チーム・クライアント開発
受信したパケットをフレームごとに決まった量しか処理しないと、押し寄せたパケットがどんどん次のフレームへ持ち越されます。
なぜ: 人が多い場所で、毎秒数千件の更新が届く → すると: メインスレッドがフレームあたりの処理量の上限に達し、読み切れない → 画面では: 他の人の動きがだんだん遅れ、まとめて反映される
症状: 早送り, 入力遅延 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
サーバーのパケットを受け取ってすぐ描画すると、ジッター(到着間隔のばらつき)がそのまま画面に表れます。
なぜ: 受信した位置をすぐに描画するか、バッファがジッターより短い → すると: 遅れて届いたパケットの分だけ止まり、まとめて届いたパケットの分だけ跳ぶ → 画面では: 他のキャラクターの動きがカクつく
症状: カクつき · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
パケットが届かない間は最後の速度のまま動かし続けて見せ、外れていたと分かると元に戻します。
なぜ: パケットの受信が途切れ、最後の方向・速度のまま移動させ続ける → すると: 実際には相手は止まっていたか、方向を変えていた → 画面では: 相手キャラクターがしばらく進んでから本当の位置へ一気に移されたり、壁をすり抜けたりする。パケットの到着間隔がばらつくと、先に進んでは戻されるのを繰り返し、震えるように動く
症状: ワープ, カクつき · 主担当 ゲーム開発チーム・クライアント開発
自分のクライアントが先に動かして見せたのに、サーバーの計算結果が違うと、自分のキャラクターが引き戻されます。
なぜ: クライアントがサーバーの確認前に先に動く(予測) → すると: サーバーが衝突・移動速度・バフを違う形で計算するか、コマンドを受け取れない → 画面では: 確認が届いたとき、自分のキャラクターが後ろへ引き戻される
症状: 引き戻し · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
一度止まった後、遅れた計算をまとめて処理しようとして、その計算のせいでさらに遅れます。
なぜ: ゲームのシミュレーションを固定間隔で回している最中に、一度止まる → すると: 遅れたステップを1フレームでまとめて計算 → 画面では: 長いフレームが次々と続いて跳ねるか、上限に達して世界全体がスローモーションになる
症状: カクつき, 早送り, スローモーション · 主担当 ゲーム開発チーム・クライアント開発
クライアントが推定したサーバー時刻がずれていると、補間のタイミングやクールタイムの判定がずれます。
なぜ: 接続時に一度だけサーバー時刻を合わせ、Pingが変わってもそのまま → すると: 補間するタイミング・クールタイムが終わる時刻がサーバーとずれる → 画面では: 相手がときどき一瞬止まる。クールタイムが終わったのにスキルが拒否される
症状: カクつき, 不発・ロールバック · 主担当 ゲーム開発チーム・クライアント開発
ゲーム内の時刻を精度の低い小数形式(float)で持っていると、起動したままの時間が長いほど時間分解能(区別できる最小の時間差)が下がり、動きやエフェクトが震えます。
なぜ: ゲーム起動後の経過時間をfloatに積算するか、そのままシェーダーに渡す → すると: 起動したままの時間が長いほど、floatで表せる最小の差が大きくなる → 画面では: 何日も起動したままのクライアントでだけ、キャラクター・アニメーション・流れるエフェクトが小刻みに震え、再起動すると直る
症状: カクつき · 主担当 ゲーム開発チーム・クライアント開発
GPUが描画したフレームを何枚かキューにためておき、モニターの周期に合わせて出力する間、入力が遅れます。
なぜ: グラフィックドライバーがフレームを1〜3枚先にキューにためる → すると: 入力が画面に反映されるまで、その分余計に時間がかかる → 画面では: Pingは低いのに、操作が重くもたつく
症状: 入力遅延, カクつき · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
長く起動しておくほどメモリが増えてだんだん重くなり、最後にはゲームが強制終了します。
なぜ: エリアを行き来するたびに、テクスチャ・UI・エフェクトが解放されずに残る → すると: GCが頻繁になり、OSのメモリが足りなくなってスワップが発生 → 画面では: 数時間プレイした後、だんだんカクつくようになり、強制終了(プレイヤーには切断のように見える)
症状: カクつき, 切断 · 主担当 ゲーム開発チーム・クライアント開発
処理されないエラーでゲームが終了します。プレイヤーには切断のように見えますが、サーバーは正常です。
なぜ: null参照、メモリ不足、グラフィックドライバーのエラー → すると: ゲームプロセスが強制終了 → 画面では: 「落ちた」という報告。同じ時刻、ほかの人は問題ない
症状: 切断 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
チートを防ぐためにゲームと一緒に動くセキュリティモジュールが、定期的に検査を行います。検査が重かったり、セキュリティサーバーとやり取りするハートビート(定期的な生存確認の信号)が遅れたりすると、カクついたり切断されたりします。
なぜ: セキュリティモジュールが定期的に、ゲームのメモリ・実行中のプログラム・ドライバーを検査 → すると: 検査の間ゲームスレッドが止まるか、ハートビートが時間どおりに届かない → 画面では: 一定の間隔で一瞬止まり、ひどいとセキュリティエラーの案内とともに切断
症状: カクつき, フリーズ, 切断 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲームはWindows、Android、iOSの上で、ほかのプログラムとCPU・メモリ・ネットワークを分け合って動いています。OSがゲームへのCPUの割り当てを遅らせたり、バッテリー節約のために速度を落としたり、バックグラウンドのアプリを一時停止させたりすると、ラグになります。
オペレーティングシステム(OS)のスケジューラー(CPUを使う順番を決める機能)が、複数のプログラムにCPU時間を分配します。ゲーム、ウイルス対策ソフト、ブラウザ、アップデートプログラムがみな「自分の番」を待っていて、OSは数msから数十msずつ(タイムスライス)交代でコアを割り当てます。OSは前面に出ているゲーム(フォアグラウンド)の優先度を少し上げてはくれますが、コアの数より処理が多ければゲームも待たされ、その待ち時間がフレームを遅らせます。
ネットワークもOSを通ります。LANカードやWi-Fiチップが受け取ったパケットは、ドライバーとOSの受信バッファに入り、ゲームが取り出すまで待ちます。ゲームが忙しくて取り出すのが遅れるとバッファがあふれ、一気に取り出すと早送りになります。モバイルでは、OSがバッテリーのために無線接続を省電力状態に切り替え、アプリそのものもたびたび一時停止させる点が特に重要です。
OSは1つしかない厨房を複数の料理人に交代で使わせる料理長です。ゲームが急ぎの料理を作っていても、ウイルススキャンという料理人がコンロを占領すれば待つしかありません。厨房が熱くなりすぎると(発熱)、火力まで落としてしまいます。
ウイルス対策ソフトのスキャン、Windows Update、配信ソフト、ブラウザの動画がコアを占有すると、ゲームスレッドがCPUを割り当ててもらえずに待たされます。
なぜ: 他のプログラムがCPUコアを長時間占有 → すると: ゲームスレッドがスケジューリング待ちになる → 画面では: フレームが遅れ、受信したパケットの処理も遅れる
症状: カクつき, 早送り · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ノートPCのバッテリーモード、スマホの省電力モード、端末の発熱によって、CPU・GPUの速度が落ちます。発熱の場合は、最初は問題なく、しばらくしてから重くなるのが特徴です。
なぜ: バッテリー・省電力モードか、端末が熱くなっている → すると: CPU・GPUのクロックを、端末によって30〜50%下げる → 画面では: 省電力モードは起動直後から、発熱は数分〜20分ほどプレイした後から、FPSが下がってカクつく
症状: カクつき, 入力遅延 · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
Windowsのデフォルトのタイマーは15.6ms単位なので、「1msだけ待つ」が実際には次のタイマー周期まで、長いと15.6msまで延びます。
なぜ: フレームレート制限・パケット送信をSleep(短い待機)で実装 → すると: OSが15.6ms単位でしか起こしてくれない → 画面では: フレーム間隔と入力の送信間隔がばらつく
症状: カクつき · 主担当 ゲーム開発チーム・クライアント開発
通知を見ようとアプリをいったんバックグラウンドに移すと、OSが数秒後にアプリを一時停止(suspend)し、その間にサーバーは自分を切断します。
なぜ: メッセージの確認・電話でゲームをバックグラウンドに移す → すると: ゲームエンジンがゲームの進行を止め、OSもすぐにアプリとネットワークを停止させる → 画面では: 戻るとすでに切断されていて、再接続
症状: 切断 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
家の外に出てWi-Fiが切れ、LTE・5Gに切り替わると、自分のIPアドレスが変わり、それまでの接続が無効になります。
なぜ: Wi-Fiの電波が弱くなり、モバイル回線に切り替わる → すると: 自分のIPアドレスが変わり、古いアドレスで確立した接続ではもうやり取りできない → 画面では: 少し止まった後に切断、または再接続
症状: フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・ネットワークインフラ
ウイルス対策ソフト・ファイアウォールがすべてのパケットを検査すると遅延が増え、行き過ぎるとゲームを攻撃と誤認してブロックします。
なぜ: セキュリティソフトが送受信パケットを1つずつ検査 → すると: パケットごとに遅延が加わり、検査が追いつかないと破棄される → 画面では: Pingが不規則に跳ねるか、接続がブロックされる
症状: カクつき, 接続不可・無限ロード · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲームの処理が忙しく、ソケット(OSが提供するネットワーク送受信のインターフェース)からパケットを取り出すのが遅れると、OSのバッファがあふれます。
なぜ: フレームが遅れ、ゲームがソケットを読むのが遅くなる → すると: OSの受信バッファがいっぱいになり、UDPは破棄され、TCPは受信ウィンドウを縮めて送信側を止めさせる → 画面では: ワープ(UDP)または早送り(TCP)
症状: ワープ, 早送り · 主担当 ゲーム開発チーム・クライアント開発
ブラウザのタブを数十個開いたままゲームを動かすと、OSがゲームのメモリの一部をディスクに追い出します。
なぜ: 全体のRAMが足りなくなる → すると: OSが今すぐには使わないゲームのメモリをディスクに移す → 画面では: その部分を再び使う瞬間に、ストレージによって数十〜数百ms止まる
症状: フリーズ, カクつき · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
グラフィックオプションが必要とするメモリがグラフィックボードのメモリより大きいと、OSがテクスチャをPCのメモリへ追い出してはまた戻すため、カクつきます。
なぜ: 高いテクスチャ設定や、人が多い場所のさまざまな装備・エフェクトで、グラフィックボードのメモリがいっぱいになる → すると: OSが今すぐには使わないテクスチャをPCのメモリに移し、必要になると遅いPCIeバスで再び戻す → 画面では: 新しい場面や新しいキャラクターが見えるたびに一瞬止まり、テクスチャがしばらくぼやける
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 外部・外部
OSが周囲のWi-Fiを探すために定期的にチャンネルを切り替えている間、通信が一瞬止まります。
なぜ: OS・ドライバーが一定周期で周囲のWi-Fiを検索 → すると: 検索している間、送受信が一瞬止まる → 画面では: 正確に一定の間隔(例:60秒ごと)でPingが跳ねる
症状: カクつき, ワープ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
有線LANアダプター・Wi-Fiチップがパケットの合間に省電力状態に入ると、再び動き出すまでに時間がかかります。
なぜ: ネットワークデバイスの省電力機能が有効か、ドライバーが古い → すると: 省電力状態からの復帰(wake-up)の遅延、ときどきデバイスの再起動 → 画面では: 不規則な遅延、まれに数秒止まる
症状: カクつき, フリーズ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
クラウド同期、大容量のダウンロード、ゲームのアップデートが同じPCで動いていると、ゲームのパケットがキューで待たされます。
なぜ: 他のアプリが上り・下りを目いっぱい使う → すると: PCとルーターのキューにゲームのパケットがたまる → 画面では: Pingの急上昇、入力遅延、早送り
症状: 入力遅延, 早送り · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ほかのウィンドウを見たりゲームを最小化したりすると、ゲームとWindowsが電力を節約するためにゲームの処理を遅くします。戻ると遅れていたパケットが押し寄せるか、すでに切断されています。
なぜ: Alt+Tabでほかのウィンドウを見るか、ゲームを最小化 → すると: ゲームが見えない間はFPSを大きく下げるか止め、Windowsも見えないプログラムの優先度を下げる → 画面では: 戻った瞬間に早送り、長くバックグラウンドにしていたら切断
症状: 早送り, カクつき, 切断 · 主担当 ゲーム開発チーム・クライアント開発
メッセンジャー・ランチャー・録画・FPS表示のソフトが、ゲーム画面の上に自分のUIを重ねて描くため、ゲームのレンダリング処理に割り込みます(フック)。フレームごとの処理が増え、ときどきゲームとぶつかって一瞬止まったり、ゲームが強制終了したりします。
なぜ: メッセンジャー・ゲームランチャー・グラフィックボードのツール・録画ソフトのオーバーレイが有効 → すると: フレームを画面に出力するたびにオーバーレイが割り込み、自分のUIを重ねて描く → 画面では: フレームが少しずつ遅れ、通知が出た瞬間に一瞬止まったり、グラフィックの不具合・強制終了が起きたりする(プレイヤーには切断のように見える)
症状: カクつき, フリーズ, 切断 · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
Pingは正常なのに操作が重いなら、テレビの映像処理やワイヤレスコントローラー、フレーム生成機能が、入力と画面の間に遅延を上乗せしているのかもしれません。
なぜ: テレビのゲームモードがオフ、Bluetooth・ワイヤレスコントローラーを使用、フレーム生成(DLSS・FSRのフレーム生成)が有効、のいずれか → すると: テレビは画質処理をしている間フレームを遅れて出力し、ワイヤレス入力は送信周期と干渉の分だけ遅れて届き、フレーム生成は次のフレームを待ってから中間フレームを作る → 画面では: PingとFPSの数字はよいのに、押してから画面に反映されるまでが遅く、入力遅延になる
症状: 入力遅延 · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
パケットが家を出る前の最後の数メートルです。距離は短いのに、ラグ報告のかなりの部分がここで生まれます。Wi-Fiは同じ無線チャネルを複数の機器で分け合い、ルーターは家族全員のトラフィックを1つのキューで送り出すからです。
Wi-Fiは同じ無線チャネル(周波数帯)を近所のルーターと分け合い、2.4GHz帯はBluetoothや電子レンジとも重なります。送信中に衝突すると少し待ってから送り直しますが、この再送が重なるとパケットの届く間隔がばらつきます。Pingの平均は問題なさそうに見えても、ときどき瞬間的に跳ねるのがWi-Fiの典型的な姿です。
ルーターは、家の中のすべての機器がインターネットに出るときに必ず通る機器です。インターネット回線が受け付けられる速度より多く送ると、ルーターやモデムの中にキューができます。キュー管理機能(SQM)のない機器は、このキューを数百ms分まで長くためてしまいます。高価なルーターでもこの機能がオフなら同じです。弟が動画をアップロードした瞬間、ゲームのパケットもそのキューの最後尾で待つことになります。この現象をバッファブロートと呼びます。
ルーターはまた、「家の中の機器 ↔ 外のサーバー」の接続をNATテーブルに記録しますが、しばらくパケットのやり取りがないとテーブルから消してしまいます。しばらく放置した後に切断される現象のよくある原因です。モバイル回線ではこれに、基地局の切り替え、無線の省電力状態、弱い電波が加わります。
ルーターはマンション団地に1つしかない出入口です。引っ越しトラック(動画のアップロード)が列を作っていると、急ぎのバイク便(ゲームのパケット)もトラックの後ろで待たなければなりません。賢いルーター(SQM)は、バイク便専用の車線を別に開けてくれます。
電波が弱かったり干渉があったりすると、無線区間で何度も送り直すことになり、パケットの到着がばらつきます。
なぜ: 壁・距離・電子レンジ・Bluetooth・近所のルーターによる電波品質の低下 → すると: 無線区間で送信に失敗 → 何度も再送 → 画面では: パケットの到着がばらつき(ジッター)、キャラクターが何度も一瞬止まる。ひどいとパケットロスでワープ
症状: カクつき, ワープ, 引き戻し · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
マンションのようにルーターが数十台ある場所では、同じチャンネルを分け合って使うため、送信の機会を待つことになります。
なぜ: 数十台のルーターが同じ2.4GHzのチャンネルを使用 → すると: 送信するには、他の機器の送信が終わってチャンネルが空くまで待機 → 画面では: 人が帰宅する夜の時間帯にジッター(到着間隔のばらつき)が増え、カクつき
症状: カクつき, 入力遅延 · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
家族の誰かが動画をアップロードしたり大きなファイルをダウンロードしたりすると、ルーターのキューに数百ms分のパケットがたまり、ゲームのパケットもその後ろで待たされます。
なぜ: 家族の動画アップロード・クラウドバックアップ、自分の配信、大容量ダウンロードで回線がいっぱいになる → すると: ルーターやモデムが、あふれたパケットを大きなキューにためておく → 画面では: ゲームのパケットもキューの後ろで待たされ、Pingが数百msまで急上昇
症状: 入力遅延, 早送り, ワープ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ルーターは、しばらくパケットがやり取りされていないアイドル接続をNATテーブルから削除します。しばらく放置した後、動いた瞬間に切断されるときによくある原因です。
なぜ: ルーターが「内側の機器 ↔ 外側のサーバー」の接続をNATテーブル(アドレス変換表)に記録 → すると: パケットがしばらくないとテーブルから削除(UDPは30〜120秒が多い) → 画面では: サーバーのパケットが家の中に入れず、切断
症状: 切断 · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
安価なルーターに数十台の機器、数千の接続が集中すると、ルーター自体が処理しきれなくなります。
なぜ: 数十台の機器、P2P・トレントが数千の接続を開く → すると: ルーターのCPUとセッションテーブルが飽和 → 画面では: パケット処理の遅延・パケットロス、新しい接続の失敗
症状: カクつき, 接続不可・無限ロード, 切断 · 主担当 外部・外部
バスや地下鉄で移動すると、基地局が切り替わる間、通信が途切れます。
なぜ: 移動に伴い、接続する基地局が切り替わる → すると: 通常は数十msの空白だが、電波が悪く切り替えに失敗すると数百ms〜数秒途切れることもある → 画面では: 止まった後にワープ、長いと切断
症状: フリーズ, ワープ, 切断 · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
スマホはしばらく通信がないと無線接続を低電力状態に落とし、次のパケットのときに再び立ち上げるため遅れます。
なぜ: しばらく通信がないと、スマホが無線接続を省電力状態に切り替える → すると: 次のパケットを送るには、接続を再び立ち上げる必要がある → 画面では: しばらく放置した後の最初の操作だけが特に遅い
症状: 入力遅延 · 主担当 ゲーム開発チーム・クライアント開発
エレベーター・地下・建物の奥では、再送が増えて速度が落ち、最終的に切断されます。
なぜ: 電波の弱い場所へ移動 → すると: 無線区間の再送の増加、速度の低下、瞬断 → 画面では: ジッター・パケットロスでカクつき・ワープ、最終的に切断
症状: カクつき, ワープ, 切断 · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
5Gの電波が弱い建物の中や5Gエリアの境界では、スマホが5GとLTEを頻繁に行き来し、切り替わるたびにPingが跳ねたり通信が一瞬途切れたりします。
なぜ: 5Gの電波が不安定な場所(建物の中、5Gエリアの境界)にいる → すると: スマホが5GとLTEの間を頻繁に切り替え、そのたびに短い空白が生じる → 画面では: 動かずにいても不規則にPingが跳ね、ときどきフリーズ・ワープ
症状: カクつき, ワープ, フリーズ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
カフェのWi-Fiのログインページや会社のファイアウォールが、ゲームの接続をブロックします。
なぜ: ログインページでの認証前か、ファイアウォールがゲームのポート・UDPを遮断 → すると: 接続の試み自体がブロックされるか、一部だけが通る → 画面では: 接続不可、ログインはできるのにゲームに入れない
症状: 接続不可・無限ロード · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
家を出たパケットは、通信事業者網や複数の通信事業者をつなぐ区間、ときには海底ケーブルを通って、サーバーのあるデータセンターに届きます。この区間の遅延はほとんどが距離と経路の選択(ルーティング)で決まり、ゲーム会社が自分で直せないことが多いです。
光は光ファイバーの中を1秒に約20万km進みます。1,000km離れたサーバーなら往復に最低10msかかり、光ファイバーを使う限り、この数字はサーバーや機器をどれだけ良くしても縮められません。実際のパケットは直線では進まず、通信事業者同士がつながる地点(ピアリング)をたどって回り道をするため、ふつうは理論値の1.5〜2倍かかります。韓国–欧州のように直線上に大きなケーブルがほとんどない区間では、東南アジア・スエズや米国を回るため2.5〜3倍(往復約230〜270ms)になります。
問題は、この経路が時間や状況によって変わることです。夜9〜11時ごろはみんなが動画を見るため通信事業者間の接続区間が混みやすく、経路情報(BGP)が変わると数秒〜数十秒(まれに数分)の間パケットが宛先に届かず、海底ケーブルが切れると数週間にわたって遠い経路に迂回します。「特定の通信事業者のユーザーだけ」「夜だけ」「海外からだけ」ラグが出るなら、まずこの層を疑います。
通信事業者網は高速道路網です。ソウルから釜山への道が空いていても距離の分だけ時間はかかり、帰宅ラッシュの料金所(ピアリング区間)は渋滞し、事故が起きればカーナビが遠回りのルートを案内します。
光ファイバーの中では、光でさえ1秒に約20万kmしか進みません。遠いサーバーは、どれほど性能が良くても遅れます。
なぜ: サーバーが遠くにある(海外サーバー、別の大陸) → すると: 距離の分だけ往復時間が延びる(1,000kmあたり最低10ms) → 画面では: すべての操作に一定の入力遅延、判定で不利
症状: 入力遅延 · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・ネットワークインフラ, ゲーム開発チーム・サーバー開発
衛星インターネットは電波が宇宙を往復するため、静止軌道衛星では往復だけで0.5秒を超えます。Starlinkのような低軌道衛星は普段は速いものの、経路を割り当て直す瞬間に遅延が揺れ、一瞬途切れることもあります。
なぜ: 自宅・船・飛行機から、静止軌道衛星や低軌道衛星のインターネット、衛星を使う機内Wi-Fiで接続 → すると: 静止軌道は高度が約36,000kmあり、往復する距離そのものが長い。低軌道は端末・衛星・地上局の経路を短い周期で割り当て直し、その瞬間に遅延・パケットロスが一時的に発生 → 画面では: 静止軌道はすべての操作に大きな入力遅延。低軌道は普段は問題ないが、一定の間隔でカクつき・ワープ
症状: 入力遅延, カクつき, ワープ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
通信事業者どうしの接続契約の都合で、近いサーバーでも遠くを回って届きます。
なぜ: 自分の通信事業者とサーバー側の通信事業者が直接つながっていない → すると: 別の国や別の都市を経由し、距離と経由する機器が増える → 画面では: 特定の通信事業者のユーザーだけPingが際立って高い
症状: 入力遅延 · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
夜9〜11時ごろは動画のトラフィックが急増し、通信事業者間の接続区間(ピアリング)が混雑しやすくなります。
なぜ: 夜の時間帯にストリーミング・ダウンロードが集中 → すると: ピアリング区間でキューの滞留とパケットロスが発生 → 画面では: 夜だけ、特定の通信事業者のユーザーにカクつき・ワープ
症状: カクつき, ワープ, 引き戻し · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
海底ケーブルが切れると、修理されるまでの数週間(長ければ数か月)は遠い迂回経路を回ることになり、残った回線は混雑します。
なぜ: ケーブルの切断・機器の故障 → すると: トラフィックが遠い迂回経路と残った回線に集中 → 画面では: 海外からの接続者でPingの急上昇とパケットロスが数日〜数週間続く
症状: 入力遅延, ワープ · 主担当 外部・外部 · 副担当 インフラチーム・ネットワークインフラ
インターネットの経路情報が変わり、再び収束するまでの数秒〜数十秒(まれに数分)の間、パケットが失われます。
なぜ: どこかの通信事業者の区間で経路情報が変わる → すると: 数秒〜数十秒の間パケットが消えるか、新しい経路に切り替わる → 画面では: 突然数秒止まった後、Pingの値が変わる(例:40→70ms)
症状: フリーズ, ワープ · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
通信事業者やデータセンターは同じ宛先への経路を複数持ち、接続ごとに1本の経路を決めて送ります。1本の経路だけが故障すると、その経路に割り当てられた人だけにラグが出続けます。
なぜ: 複数の回線を束ねた区間で、1本の回線や1台の機器が不良、または混雑 → すると: アドレス・ポートの組み合わせ(ハッシュ)で経路が決まり、その経路に割り当てられた接続だけにパケットロス・遅延 → 画面では: 同じ地域・同じ通信事業者なのに一部の人だけが継続的にワープ。再接続すると直ることもある
症状: ワープ, 引き戻し, カクつき · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
データ使用量の上限を超えた場合や、特定のトラフィックを管理する料金プランでは、パケットが遅らされたり破棄されたりします。
なぜ: 料金プランのデータ容量を使い切った後の速度制限、または特定トラフィックの制限 → すると: パケットが待たされるか破棄される → 画面では: 一定の使用量を超えた後にラグ、特にモバイル
症状: 入力遅延, ワープ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
一部のネットワークでは、特定のUDPアドレス・ポートをブロックしたりUDPの速度を制限したりし、パケット検査装置が識別できないプロトコルを遮断します。UDPで通信するゲームは、そのネットワークでは接続できなかったり、頻繁に切断されたりします。
なぜ: UDPの速度を制限する一部の通信事業者網や、国・通信事業者単位のトラフィック検査(検閲)装置があるネットワークから接続 → すると: 特定のUDPアドレス・ポートをブロック、混雑する時間帯にUDPの速度を制限、許可リストにないポート・プロトコルを遮断、または最初の数パケットだけ通してからブロック → 画面では: 特定の国・通信事業者のユーザーだけ接続不可・無限ロード、接続してもすぐに切断、混雑する時間帯にパケットロスでワープ
症状: 接続不可・無限ロード, 切断, ワープ · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
端子の接触不良や古いケーブル、モデムの異常は、継続的なパケットロスと周期的な回線断を引き起こします。
なぜ: ケーブルの損傷、接触不良、モデム・ONU(光回線終端装置)の異常 → すると: ビットエラーでパケットが破棄され、ときどき回線の再接続で数秒〜1分ほど途切れることもある → 画面では: 継続的な少量のパケットロス、ときどき数秒のフリーズや切断
症状: ワープ, フリーズ, 切断 · 主担当 外部・外部
サーバー名をアドレスに変換するDNSが遅かったり失敗したりすると、ログインサーバーやアップデートサーバーを見つけられません。
なぜ: 通信事業者のDNSの障害または設定ミス → すると: ログイン・アップデートサーバーのアドレスが見つからない → 画面では: 接続ボタンを押した後に長く待たされるか接続不可。すでに接続している人は問題ない
症状: 接続不可・無限ロード · 主担当 外部・外部 · 副担当 ゲーム開発チーム・クライアント開発
ゲーム会社や同じネットワーク内の別の宛先を狙った大量の攻撃が、共有回線を埋め尽くします。
なぜ: 大量の攻撃トラフィックが発生 → すると: 同じ回線を使う正常なトラフィックまで押し出されて破棄される → 画面では: 多くの人が同時にワープ・切断・接続不可
症状: ワープ, 切断, 接続不可・無限ロード · 主担当 インフラチーム・ネットワークインフラ · 副担当 外部・外部
モバイル回線や一部の通信事業者では、複数の契約者が1つのIPを共有し、アイドル接続のマッピングを短時間で削除します。
なぜ: 通信事業者の機器が膨大な数の契約者のセッションテーブルを管理 → すると: セッションテーブルの上限、短いアイドルタイムアウト → 画面では: しばらく放置した後に切断、同じIPを使う人たちがまとめてブロックされる誤検知
症状: 切断, 接続不可・無限ロード · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・ネットワークインフラ
VPNやラグ軽減ツールを使うと、パケットはその会社の中継サーバーを経由します。中継サーバーが遠かったり混雑していたりすると、かえって遅くなります。
なぜ: VPN・ラグ軽減ツールが、ゲームのパケットをすべて中継サーバーに回す → すると: 中継サーバーまでの距離と混雑が加わり、トンネルのヘッダーのせいでMTU(一度に送れるパケットサイズ)も小さくなる → 画面では: Pingの上昇とパケットロス、同じ中継アドレスを使う人と一緒にブロックされて接続不可
症状: 入力遅延, ワープ, 接続不可・無限ロード · 主担当 外部・外部 · 副担当 インフラチーム・ネットワークインフラ, ゲーム開発チーム・サーバー開発
サーバーに届く直前、パケットはルーター・DDoS対策装置・ファイアウォール・ロードバランサー・スイッチを順に通過します。ふだんは1msもかからない区間ですが、機器が1台でも容量いっぱいになったり障害が発生したりすると、サーバー全体の数千人が同時に影響を受けます。
それぞれの機器は役割が異なります。ルーターは経路を決め、DDoS対策装置は攻撃トラフィックを取り除き、ファイアウォールは許可された接続だけを通して、すべての接続をセッションテーブルで追跡します。ロードバランサーは入ってきた接続を複数のサーバーに振り分け、スイッチはサーバー同士をつなぎます。
これらの機器に共通する弱点は、テーブルサイズとバッファサイズです。ファイアウォールのセッションテーブルがいっぱいになると新しい接続を受け付けられず、ロードバランサーはアイドル接続を一定時間後に消してしまい、スイッチの小さなバッファは、複数のサーバーが同じ瞬間に数千人へ一気にパケットを送ると(ワールドボスの出現など)1msもたたずにあふれます。さらに、機器が1台故障して予備機に切り替わる(フェイルオーバー)数秒の間は、全員が止まります。
データセンターの入口は空港の保安検査場と搭乗ゲートです。検査場(ファイアウォール)は名簿にある人だけを通し、名簿の欄が埋まるとそれ以上受け付けられません。ゲートの係員(ロードバランサー)は、長い間じっと座っている乗客を「立ち去った人」とみなして名簿から消します。
ファイアウォールは、通過させたすべての接続をセッションテーブルに記録して追跡します。テーブルがいっぱいになると、新しい接続を受け付けられなくなります。
なぜ: 接続の殺到や攻撃でセッション数が上限に到達 → すると: 新しい接続を記録する空きエントリがなく拒否 → 画面では: 新たに入ろうとする人は接続不可・無限ロード、一部の既存の接続も切断
症状: 接続不可・無限ロード, 切断 · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
攻撃を防ぐためにトラフィックをスクラビングセンターに回すと経路が長くなり、正常なユーザーを攻撃と誤認してブロックすることもあります。
なぜ: 攻撃の検知後(または常時)、入ってくるトラフィックをスクラビングセンターに迂回 → すると: 経路が長くなり、一部の正常なパケットを攻撃と判定 → 画面では: 全体のPingが上昇、特定の地域・通信事業者だけ接続不可
症状: 入力遅延, 接続不可・無限ロード, ワープ · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
ロードバランサーは、アイドル状態の接続を一定時間後に削除します。ゲーム側は接続が維持されているものとみなしているうちに、切断されてしまいます。
なぜ: プレイヤーがしばらくパケットを何も送らない(会話ウィンドウ、離席) → すると: ロードバランサーがアイドル接続を整理(よくあるデフォルト値は60〜350秒) → 画面では: 再び動いた瞬間に切断
症状: 切断 · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
クラウドのサーバーに付いているファイアウォール(セキュリティグループ)も接続を追跡し、アイドル接続の追跡エントリは決められた時間の後に期限切れになります。ロードバランサーを通さずに直接つなぐサーバーでも、しばらく放置していたプレイヤーが切断されることがあります。
なぜ: セキュリティグループがゲームの接続を追跡する設定(特定のアドレスだけ許可、アウトバウンドルールの制限、NLB経由など) → すると: しばらくアイドル状態だった接続の追跡エントリが期限切れになり、その後に届いたパケットをセキュリティグループが黙って破棄 → 画面では: 離席後に再び動くと反応がないまま切断。サーバープログラムはしばらく気づかない
症状: 切断 · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・クライアント開発, ゲーム開発チーム・サーバー開発
プライベートサブネットのサーバーから外部(プラットフォーム認証・決済・外部API)への接続は、NATゲートウェイがアドレスとポートを変換して送り出します。同じ宛先への同時接続がゲートウェイのポート上限を超えると、新しい接続が失敗します。
なぜ: サーバー群が、プラットフォーム認証・決済のような同じ外部アドレスへ短い接続を大量に開くか、接続を長く開いたままにする → すると: NATゲートウェイがその宛先に使う送信元ポートをこれ以上割り当てられず、新しい接続が失敗 → 画面では: ゲーム内は問題ないのに、ログイン・決済・報酬付与のように外部を呼び出す機能だけが失敗するか遅れる(接続不可・無限ロード、不発・ロールバック)
症状: 接続不可・無限ロード, 不発・ロールバック · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
接続が1台のサーバーだけに集中したり、すでに落ちたサーバーに人を送り続けたりします。
なぜ: 振り分けルールが合っていないか、ヘルスチェックが実際の状態を捉えられていない → すると: 1台のサーバーだけが過負荷、または落ちたサーバーへの接続試行 → 画面では: 一部のチャンネル・一部の人だけスローモーション、接続不可・無限ロード
症状: スローモーション, 接続不可・無限ロード · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発
複数のサーバーが同じ瞬間に数千人へ一斉にパケットを送ると、そのトラフィックが集まるスイッチポートの小さなバッファが1ms足らずであふれます。
なぜ: ワールドボスの出現・大規模スキル、または複数サーバーのティックが同じ瞬間に重なって一斉に送信 → すると: 複数のポートが1つのポートに集まる場所や、速いポートから遅いポートへ渡る場所のバッファ(ポートあたり数百KB〜数MB)が瞬間的にいっぱいになる → 画面では: 一部のパケットが破棄され、多くの人が同時にワープ・スキル不発
症状: ワープ, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ, インフラチーム・サーバーインフラ
アップデートデータの配信・ログ転送・バックアップがゲームと同じ回線を使うと、回線がいっぱいになります。
なぜ: 大容量の転送が同じ回線を占有 → すると: 回線のキューとパケットロスが増加 → 画面では: サーバー全体でPingの上昇とワープ
症状: 入力遅延, ワープ · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
ルーター・ファイアウォールの1台が故障して予備機に切り替わる(フェイルオーバー)数秒の間、全員が止まります。
なぜ: 機器の故障またはメンテナンスで予備機に切り替え → すると: 切り替えに数秒、セッション情報が同期されていなければ接続がリセットされる → 画面では: サーバーの全ユーザーが同時にフリーズ、大量の切断
症状: フリーズ, 切断 · 主担当 インフラチーム・ネットワークインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
光モジュールやケーブルが不良だと、その経路を通るパケットが一定の割合で壊れます。
なぜ: 光モジュール・ケーブルの不良でビットエラー → すると: 壊れたパケットは機器が黙って破棄 → 画面では: その経路を使う一部のサーバー・ユーザーだけが、継続的なパケットロスでワープ・引き戻し
症状: ワープ, 引き戻し · 主担当 インフラチーム・ネットワークインフラ
途中の区間のMTU(一度に送れるサイズ)が小さくなっているのにサイズ超過の通知がブロックされると、大きなパケットだけが消え続けます。
なぜ: トンネル・VPNの区間でMTUが小さくなる → すると: サイズ超過の通知(ICMP)がファイアウォールでブロックされ、送信側が気づかない → 画面では: インベントリ・キャラクター一覧のような大きな画面を開いたときだけフリーズした後に切断
症状: フリーズ, 切断, 接続不可・無限ロード · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・サーバー開発
サーバーに挿さったネットワークカードは、1秒に数十万〜数百万個のパケットを受け取ってCPUに渡します。ここで処理が追いつかないと、サーバープログラムはパケットが届いたことすら知らないまま失います。
NICは届いたパケットをリングバッファ(決まった数のスロットを使い回す受信バッファ)に順に入れ、CPUに「パケットが来ました」と知らせます(割り込み)。CPUはリングバッファからパケットを取り出してOSに渡します。CPUが取り出す速度より速く入ってくるとスロットがすべて埋まり、その後に届いたパケットは破棄されます。ネットワークカードの統計(ethtool -S)の数字が黙って増えるだけで、ゲームサーバーのログには何のエラーも残らないため、見つけにくいラグです。
最近のNICには、受信キュー(リングバッファ)を複数持ち、複数のCPUコアに振り分けて知らせる機能(RSS)がありますが、設定されていなかったりトラフィックが1つのキューに偏ったりすると、1つのコアだけが100%になってボトルネックになります。クラウドのサーバーなら、NICの手前に1秒あたりのパケット数・帯域幅・接続数の上限が別にあり、超えた分はサーバーに届く前に破棄されます。CPUやリングバッファのようなふだんのメトリクスには現れず、AWSならENAドライバーの統計(ethtool -Sのpps_allowance_exceededなど)にだけ残ります。
NICはマンションの郵便受け、リングバッファは郵便受けの区画の数、割り込みは配達員が鳴らすチャイムです。郵便物が大量に届いているのに取り出す人が1人しかいなければ、区画があふれて手紙が床に落ちます。RSSは取り出す人を複数置くことです。
NICがパケット到着の割り込みを1つのCPUコアにだけ送ると、そのコアがボトルネックになります。
なぜ: 受信キューが1つだけか、複数のコアに分散するRSSが無効 → すると: 1つのコアが100%になり、パケットを時間内に取り出せない → 画面では: 人が集中したときにサーバー全体でパケットロスと遅延(ワープ・入力遅延)
症状: ワープ, 引き戻し, 入力遅延 · 主担当 インフラチーム・サーバーインフラ
NICがパケットを一時的に入れておくリングバッファが小さいと、瞬間的に集中したときにバッファがあふれて破棄されます。
なぜ: リングバッファがデフォルト値(ドライバーごとにスロット256〜2,048個)のままで小さい → すると: バースト時にCPUが取り出す前にバッファがあふれる → 画面では: バーストの瞬間だけパケットロス(ワープ・スキル不発)。ゲームサーバーのログには痕跡がない
症状: ワープ, 不発・ロールバック · 主担当 インフラチーム・サーバーインフラ
CPUの負担を減らすために、パケットをまとめてから一度に知らせると、まとめる時間の分だけ遅れます。
なぜ: NICが一定の時間・個数だけまとめてから通知 → すると: まとめている間、パケットが待たされる → 画面では: わずかな遅延の増加。通常は小さいが、過剰だとms単位
症状: 入力遅延 · 主担当 インフラチーム・サーバーインフラ
クラウドのサーバーには種類ごとに毎秒のパケット数・帯域幅の上限があり、超えると黙って破棄されます。
なぜ: 同時接続数が増えて、毎秒のパケット数がインスタンスの上限を超える → すると: クラウドのネットワークが超過分を破棄 → 画面では: 原因のわからないパケットロスでワープ・スキル不発。サーバーのCPUには余裕がある
症状: ワープ, 不発・ロールバック · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
1Gbps・10Gbpsのカードを限界まで使うと、送信キューが長くなり、最終的に破棄されます。
なぜ: ブロードキャストの増加で送信量がカードの限界に到達 → すると: 送信キューが長くなり、あふれると破棄 → 画面では: サーバー全体で遅延・パケットロス(入力遅延・ワープ)
症状: 入力遅延, ワープ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
同じ物理サーバー上のほかの仮想マシンがネットワーク・CPUを大量に使うと、自分のサーバーの処理が不規則に遅れます。
なぜ: 同じ物理サーバー上のほかの仮想マシンがリソースを大量に使用 → すると: 自分の仮想マシンのパケット処理が不規則に遅れる → 画面では: はっきりした原因がないのに、ときどきジッター(到着間隔のばらつき)が生じてカクつき
症状: カクつき · 主担当 インフラチーム・サーバーインフラ · 副担当 外部・外部
クラウド事業者は物理サーバー(ホスト)をメンテナンスするとき、仮想マシンを別のホストに移したり(ライブマイグレーション)、一時的に止めたりします。その間はサーバー全体が止まり、止まる時間が長いと接続が切れます。
なぜ: 事業者がホストのメンテナンスや故障予測のために、仮想マシンを別のホストに移すか一時停止 → すると: 移している間はCPU・メモリ・ネットワークが遅くなり、最後に仮想マシンが一瞬完全に止まる(事業者と方式によって1秒未満〜30秒前後) → 画面では: サーバーの全員が同時にフリーズした後に早送り・ワープ、停止がタイムアウトより長ければ大量の切断
症状: フリーズ, 早送り, ワープ, 切断 · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, 外部・外部
ドライバーのバグや機能の誤動作でカードが止まり、再起動している間はすべての送受信が途切れます。
なぜ: ドライバーのバグ、オフロード機能の誤動作 → すると: NICが止まって再起動(数秒) → 画面では: そのサーバーの全員が一緒にフリーズした後、ワープするか切断
症状: フリーズ, 切断 · 主担当 インフラチーム・サーバーインフラ
複数のパケットを1つにまとめてCPUの負担を減らす機能です。設定によっては、小さなゲームのパケットが、一緒にまとめる次のパケットを少し待つことがあります。
なぜ: NIC・カーネルが到着したパケットをまとめて処理 → すると: ハードウェアによる結合(LRO)や結合の待ち時間の設定が有効だと、次のパケットを待って少し待機 → 画面では: わずかな遅延の増加(たいてい数十µs以下)
症状: 入力遅延 · 主担当 インフラチーム・サーバーインフラ
サーバーのLinux・Windowsカーネルは、接続を受け付け、ソケットバッファを管理し、CPUとメモリをゲームサーバープログラムに分配します。ほとんどのデフォルト値はさまざまな用途に広く合わせた保守的な値なので、数万人が長時間接続し続けるゲームサーバーにはそのままでは合わないことが多いです。
新しい接続が来ると、カーネルは接続要求を接続待ちキュー(backlog)に入れておき、ゲームサーバーが1つずつ受け取ります。キューがいっぱいになると、Linuxは新しい要求を黙って破棄し、Windowsは拒否の応答を返します。Linuxでは接続ごとに、開いたファイルや接続に付く番号であるファイルディスクリプタ(fd)が1つずつ必要で、1つのプロセスが持てるfdの数にも上限があります。メンテ明けに数万人が同時に接続ボタンを押すと、接続待ちキューとfdが真っ先に尽きます。
カーネルはまた、メモリが足りなくなるとディスクに追い出し(スワップ、有効にしている場合)、Linuxは本当に尽きるとメモリを最も多く使っているプロセスを選んで強制終了させます(OOM Killer)。ゲームサーバーはたいていそのサーバーで最もメモリを使うプロセスなので、真っ先に終了の対象になります。コンテナにメモリ上限を設定していれば、サーバー全体には余裕があっても上限に達した瞬間に同じことが起きます。時刻同期(NTP)、定期ジョブ、コンテナのCPU上限、仮想マシンのCPUスチール(ほかの仮想マシンが物理CPUを使っている間の待ち時間)のように、ゲームとは関係なさそうな処理も、サーバーをときどき短時間止めたりタイマーをずらしたりします。
サーバーOSは遊園地の入場ゲートと管理事務所です。開園時間(メンテ終了)に全員が押し寄せるとゲート前の列(backlog)があふれ、配るリストバンド(ファイルディスクリプタ)がなくなるとそれ以上入れません。
メンテ明けに数万人が同時に接続すると、カーネルの接続待ちキュー(backlog)があふれ、接続要求が破棄されます。
なぜ: メンテ終了と同時に、ゲームサーバーがacceptで接続を処理する速度を上回る勢いで接続が殺到 → すると: カーネルの接続待ちキュー(backlog。サーバーのコードがlistenに渡した値とカーネルの上限のうち小さいほう)が満杯 → 画面では: 接続要求が破棄されて再試行が繰り返され、接続不可・無限ロード
症状: 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
接続ごとにファイルディスクリプタ(fd。OSが開いているファイルやソケットに付ける番号)が必要ですが、1つのプロセスが開けるfdの数には上限があります。
なぜ: 同時接続数がプロセスのファイルディスクリプタ上限に到達 → すると: サーバーが新しい接続を受け付けられない(Too many open files)。ログファイルやDB接続を開く処理も同時に失敗 → 画面では: ちょうど一定の人数から先は誰も入れない接続不可・無限ロード
症状: 接続不可・無限ロード · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
送受信バッファが小さいと、バーストトラフィックが集中したときに、UDPで受信したパケットは破棄され、TCPの送信はバッファに空きがなくブロックされます。
なぜ: SO_SNDBUF・SO_RCVBUFがデフォルト値のまま、または小さすぎる → すると: バーストや、受信スレッドが一瞬止まった間にUDPの受信バッファがあふれて破棄、TCPは送信バッファに空きがなく待機 → 画面では: ワープ(UDPのパケットロス)または早送り(TCPの待機)
症状: ワープ, 早送り · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
コア数よりはるかに多いスレッドを動かすと、OSがそれらを切り替えて実行するだけでCPUを消費します。
なぜ: 接続ごとにスレッドを作るなどして、スレッドが数百〜数千個 → すると: コンテキストスイッチ(実行するスレッドの切り替え)のコストとキャッシュミスが増加 → 画面では: CPUはビジーなのにスループットは低く、ティックがばらついてカクつき・スローモーション
症状: カクつき, スローモーション · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
物理サーバー(ハイパーバイザー)が仮想マシンのCPU時間を一時的にほかの仮想マシンに回している間(CPUスチール)、ゲームサーバーが止まります。
なぜ: 同じホスト上のほかの仮想マシンがCPUを大量に使用 → すると: 自分の仮想マシンが数ms〜数十msずつ実行機会を失う → 画面では: 原因不明のティック時間の急増で、カクつき・フリーズ
症状: カクつき, フリーズ · 主担当 インフラチーム・サーバーインフラ · 副担当 外部・外部
コンテナにCPU上限をかけると、決まった周期(通常100ms)の中でクォータを使い切った時点から、残りの時間は強制的に止められます(スロットリング)。
なぜ: Kubernetesなどで、ゲームサーバーのコンテナにCPU上限(limit)を設定している → すると: ティックの計算が集中した瞬間にクォータを使い切り、次の周期まで数十ms停止 → 画面では: 平均CPUは低いのにティックが周期的に跳ねて、カクつき・スローモーション
症状: カクつき, スローモーション · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
使われていないCPUコアは、電力を節約するために深い省電力状態(C-state)に入り、周波数も下げます。パケットやタイマーが来ると、復帰して周波数を上げるまでに時間がかかるため、小さなパケットの処理に遅延が加わります。
なぜ: OSの周波数制御ポリシー(governor)やBIOSの電源設定が、深いC-stateと低い周波数を許可している → すると: 休んでいたコアが深い省電力状態から復帰するたびに最大数百µs遅れ、周波数が低く固定されているとティックの計算自体が遅くなる → 画面では: 普段は体感しにくいが、サーバー間の呼び出しが多いと積み重なり、空いているときにかえって応答が遅くなる入力遅延。周波数が低く固定されていると、人が集中したときにティックが遅れてスローモーション
症状: 入力遅延, スローモーション · 主担当 インフラチーム・サーバーインフラ
Linuxはメモリが尽きると、メモリを最も多く使っているプロセスを選んで強制終了します。たいていはゲームサーバーです。
なぜ: リークや急増でメモリが枯渇、またはコンテナのメモリ上限に到達 → すると: カーネルがゲームサーバーのプロセスを強制終了 → 画面では: そのサーバーの全員が同時に切断、直近の進行がロールバックされることもある
症状: 切断, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
OSがヒュージページ(huge page)を作るためにメモリをコンパクションしたり、空きメモリを回収したりしている間、プロセスが止まります。
なぜ: 空きメモリが減る、またはヒュージページ機能(THP)がメモリのコンパクションを実行 → すると: メモリを要求したスレッドが、回収・コンパクションが終わるまで待機 → 画面では: 不規則なサーバーの停止(数ms〜数百ms)
症状: フリーズ, カクつき · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
サーバーの時刻が一度に数秒前後に調整されると、システム時刻に依存するタイマーが一斉に発火したり止まったりします。
なぜ: 時刻同期が時刻を一度に大きく調整 → すると: タイマーがまとめて発火したり止まったりし、タイムアウトが誤って判定される → 画面では: バフ・クールタイムの異常、一斉に切断、早送り
症状: 早送り, 切断, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
毎日同じ時刻に動くログ圧縮・バックアップ・セキュリティスキャンが、CPUとディスクを占有します。
なぜ: 決まった時刻にOSのジョブが実行される → すると: CPU・ディスクをゲームサーバーと取り合う → 画面では: 毎日早朝4時のように、決まった時刻にカクつき・スローモーション
症状: カクつき, スローモーション · 主担当 インフラチーム・サーバーインフラ
ゲームのコードは変わっていないのに、サーバーのOS・カーネル・ドライバー・ファームウェアをアップデートしてから遅くなるケースです。アップデートによって、デフォルト値、スケジューラー、CPU脆弱性の緩和策(mitigations)、ドライバーの動作が変わることがあります。
なぜ: 定期的なセキュリティパッチや新しいサーバーイメージで、カーネル・ドライバー・ファームウェアが変わる → すると: デフォルト値やスケジューラーが変わったり新しい脆弱性の緩和策が有効になったりして、同じ処理により多くのCPU時間がかかり、スレッドにCPUが割り当てられる順序も変わる → 画面では: 問題なかったサーバーがアップデートした日から常に少し遅くなって入力遅延、人が集中するとカクつき・スローモーション
症状: 入力遅延, カクつき, スローモーション · 主担当 インフラチーム・サーバーインフラ
Linuxのファイアウォールがすべての接続を記録する接続追跡(conntrack)テーブルが上限に達すると、新しいパケットを破棄します。
なぜ: 接続の殺到や短い接続の繰り返しで、接続の記録が増加 → すると: テーブルが満杯になり、新しい接続と一部のパケットを破棄 → 画面では: 接続不可、原因不明のパケットロスでワープ
症状: 接続不可・無限ロード, ワープ · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, ゲーム開発チーム・クライアント開発
ゲームサーバーがDBやほかのサーバーへの接続を短時間で頻繁に張っては切ると、切れた接続がしばらくポートを占有し、新しい接続を開けなくなります。
なぜ: リクエストごとに新しい接続を開いて閉じる → すると: 先に閉じた側が約60秒(Linux)の間ポートを占有し(TIME_WAIT)、使えるポートが尽きる → 画面では: 内部リクエストが失敗し、保存の失敗・機能のエラー
症状: 不発・ロールバック, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
ゲームがネットワークでデータをやり取りする方法を決める部分です。同じ回線でも、どのプロトコルを使い、ソケットオプションをどう設定するかによって、パケットを1つ失ったときに「一瞬引っかかる」だけで済むこともあれば、「1秒止まってから一気に動く」ことにもなります。
TCPは、送った順番どおりに漏れなく届けることを保証します。その代わり、1つでも失うと、再び受け取るまでは後から届いたものまですべてゲームに渡さずに待ちます。UDPは何も保証しません。届いたものは待たずにすぐ渡しますが、失ったものはゲーム側で処理しなければなりません。そのため、アクション性の強いゲームはUDPの上に必要な分だけ信頼性を自前で実装し(信頼性UDP)、多くのMMOは実装が簡単なTCPを使って、その弱点を受け入れています。
ソケットオプションは、この動作の細かい設定です。小さなパケットをまとめてから送るか(TCP_NODELAY)、送受信バッファをどれだけ確保するか(SO_SNDBUF、SO_RCVBUF)、死んだ接続にいつ気づくか(SO_KEEPALIVE、TCP_USER_TIMEOUT)、閉じるときに残ったデータをどうするか(SO_LINGER)。デフォルト値はほとんどが、大きなデータを少ないパケットで効率よく送る方向に合わせてあるため、小さなパケットを頻繁にやり取りするゲームには不利なことが多いです。
TCPは受け取ったデータを送られた順番どおりにしかゲームに渡しません。17番のパケットが消えると、18〜30番がすでに届いていても、17番が再び届くまで全部待ちます(HOLブロッキング)。UDPは届いた順に渡すので、17番が最後まで届かなくても、残りは時間どおりに処理されます。
再送がなぜ起きるのか(Wi-Fi、輻輳、MTUブラックホール、不要な再送など)と原因の探し方は、06 TCP再送で原因ごとに扱います。
TCPは順序を守るため、失われたパケットを1つ受け取り直すまで、後から届いたパケットをゲームに渡しません。
なぜ: パケットが1つ消失 → すると: 後続のパケットは届いているが、受信バッファで待機 → 画面では: 止まった後に一気に解放されて早送り
症状: フリーズ, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
再送がまた失敗するたびに待ち時間が2倍に延びるため、短い回線断が長い停止になります。
なぜ: 回線が一瞬切れて、再送も続けて失敗 → すると: 次の試行までの時間が0.3 → 0.6 → 1.2 → 2.4秒のように2倍ずつ延びる(Ping 100msの場合) → 画面では: 回線が切れたのは1秒なのに、ゲームは2秒以上止まる。さらに長く切れると最終的に切断
症状: フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
小さなパケットをまとめて送るNagleアルゴリズムと、ACKを遅らせて送る遅延ACKがかみ合い、メッセージを分けて書き込むたびに40〜200msずつ遅延します。
なぜ: TCP_NODELAYを有効にしないまま、小さなメッセージを分けて書き込む → すると: 送信側はACKを待ち、受信側はACKを遅らせて送る → 画面では: 回線のPingは低いのに、すべての操作が一様にもたつく入力遅延
症状: 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
回線の遅い1人の送信バッファが満杯なのに、ブロッキング方式(バッファに空きができるまで呼び出しが戻らない送信)で送ると、サーバーのスレッドがその1人を待ちます。
なぜ: 遅いクライアントの送信バッファが満杯 → すると: ブロッキング送信のため、サーバーのスレッドがバッファに空きができるまで待機 → 画面では: そのスレッドが担当する全員がフリーズ・スローモーション
症状: フリーズ, スローモーション · 主担当 ゲーム開発チーム・サーバー開発
送るデータがたまり続けるクライアントに対して、サーバーが古い更新を破棄したり接続を切ったりします。
なぜ: クライアントの回線が、サーバーが送る量に追いつかない → すると: サーバーが古い更新を破棄するか、上限を超えたら接続を切断 → 画面では: その人だけワープまたは切断
症状: ワープ, 切断 · 主担当 ゲーム開発チーム・サーバー開発
相手が終了の合図なしに消えると、TCPはかなり時間がたってから検知します。keepalive(アイドル接続が生きているかを確認するTCPの機能)はデフォルトで無効で、有効にしても2時間アイドル状態が続かないと確認を始めません。
なぜ: クライアントが電源断や回線断で、終了の合図なしに消える → すると: サーバーは接続が生きているとみなす(keepaliveのデフォルトは7,200秒。送信中のデータがあれば再送をあきらめるまで約15分) → 画面では: キャラクターがゴーストとして残り、再接続すると「すでに接続中」エラー
症状: 接続不可・無限ロード, 表示されない・ゴースト · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
MTU(一度に送れるサイズ)を超えるUDPパケットはIP層でフラグメント化され、フラグメントを1つ失うだけでパケット全体が破棄されます。
なぜ: 人の多い場所のスナップショットが1,500バイトを超える → すると: 複数のフラグメントに分割して送信、1つでも失うと全体を破棄 → 画面では: 大きなパケットほどロス率が数倍になる。混雑した場所でだけワープ
症状: ワープ · 主担当 ゲーム開発チーム・サーバー開発
UDPの上に独自に作った再送ルールが保守的すぎると復旧が遅れ、攻撃的すぎると回線をさらに詰まらせます。
なぜ: 再送の間隔・回数・ウィンドウサイズの設定が回線に合っていない → すると: 復旧の遅れ、または重複送信による輻輳の悪化 → 画面では: スキル不発、早送り、輻輳時にさらにひどいラグ
症状: 不発・ロールバック, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
TCPはしばらくアイドル状態が続くと輻輳ウィンドウ(一度に送れる量)を再び縮めるため、急に大きなデータを送るときに何回かに分けて送ります。
なぜ: アイドル状態だった接続で、街への入場など大きなデータを送る → すると: 輻輳ウィンドウが縮んでいるため、複数の往復に分けて送信 → 画面では: 入場直後、周りのキャラクターやNPCが往復数回分遅れて表示される(遠いサーバーほど目立つ)
症状: 入力遅延, 表示されない・ゴースト · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
TCPはパケットロスを輻輳のシグナルとみなし、送信速度を30〜50%落とします。Wi-Fiでのパケットロスにも同じように反応します。
なぜ: 送る量が多いときに、Wi-Fiや回線でわずかなパケットロスが発生 → すると: TCPが送信速度を大きく落とし、ゆっくり回復(Linux・WindowsのデフォルトであるCUBICは30%落とす) → 画面では: 人の多い場所で更新が遅れて早送り・入力遅延
症状: 早送り, 入力遅延 · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
サーバーが接続を急に切ると、最後に送った案内や保存完了の通知が失われます。
なぜ: サーバーが接続を強制終了(RST)で閉じる。SO_LINGERを0秒にしたり、受信したデータを読み切らずに閉じたりすると起きる → すると: まだ送信中だったキックの理由や最後のデータが破棄される → 画面では: 理由の分からない「不明なエラーにより接続が切断されました」
症状: 切断 · 主担当 ゲーム開発チーム・サーバー開発
1つのソケットを待っている間、スレッドがほかの処理をできない構造では、人が増えるほど全体が遅くなります。
なぜ: 接続ごとに読み書きを待つ方式 → すると: 1つの接続の遅延が、同じスレッドのほかの接続に波及 → 画面では: 同時接続数が増えるほど、全体がスローモーション・入力遅延
症状: スローモーション, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発
同じポートを複数のプロセスで分担して受け付けると、カーネルは接続ごとにアドレスのハッシュで担当プロセスを決め、その後は変更しません。担当プロセスが1つ止まると、そこに割り当てられた人だけが待たされます。
なぜ: ゲートウェイ・ログインサーバーがSO_REUSEPORTで複数のプロセスを起動 → すると: 1つのプロセスがGCや過負荷で止まっても、そこに割り当てられた新しい接続とUDPパケットはほかのプロセスに回されない → 画面では: 一部の人だけ接続不可・フリーズ。プロセス数が変わる再起動時には、一部のUDPセッションが切れる
症状: 接続不可・無限ロード, フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
Windowsサーバーがすでに去ったクライアントにUDPを送ると、「ポート到達不能」(ICMP)の通知が返ってきます。その通知のせいで次の受信呼び出しがエラーで終わりますが、サーバーのコードがこのエラーをソケット自体の故障として扱うと、そのソケットを使っている全員が影響を受けます。
なぜ: 出ていったばかりのクライアントのアドレスにUDPを送り続け、「ポート到達不能」(ICMP)の通知が返ってくる → すると: Windowsが次の受信呼び出しをWSAECONNRESET(10054)エラーで終わらせ、サーバーのコードが受信を止めるかソケットを閉じる → 画面では: そのソケットを使っていた全員が一斉にフリーズ・切断
症状: 切断, フリーズ · 主担当 ゲーム開発チーム・サーバー開発
ゲームロジックを実際に計算するプログラムです。移動、戦闘、モンスターAI、視界計算、ブロードキャストが、すべて「ティック」1回の中で終わらなければなりません。人が1か所に集まるほど、視界計算と送るパケットは人数の2乗で増えます。
サーバーは決まったティック間隔でゲームの状態を計算します。20ティックのサーバーなら50msに1回、その間にすべてのプレイヤーの入力を適用し、モンスターを動かし、誰が誰を見られるかを計算し(視界、AOI)、変化した内容を見えるすべての人に送ります。この50msがティックバジェットです。バジェットを超えると次のティックが遅れます。ティックごとにゲーム内時間を決まった分だけ進めるサーバーでは、ゲーム内の時間全体がゆっくり流れ(スローモーション)、実際に経過した時間分を一度に進めるサーバーでは、速度は保たれる代わりにパケットがまばらになり、カクついたりワープしたりします。どちらにしても反応は遅れます。ゲームスレッド1本がサーバー(チャンネル)全体を担当していればそのサーバーの全員が、エリアごとにスレッドを分けていればそのエリアの人たちが一緒に影響を受けます。
問題は人数です。全員同士を比べると、100人なら約1万回、1,000人なら約100万回を毎ティック調べなければなりません。そのためサーバーはマップをグリッドに分け、近いセル同士だけを比べますが、ワールドボス、攻城戦、街の広場のイベントのように全員が1つのセルの近くに集まると、グリッドの効果が薄れ、計算量と送るデータが爆発的に増えます。さらに、複数のスレッドが同じデータを巡って待つロックや、ティックの途中でDBの応答を待つ同期呼び出しが重なると、待っている間はそのスレッドが担当する全員が一緒に止まります。
サーバーのティックは指揮者の拍子です。オーケストラの団員(プレイヤー)が増えるほど1拍の間に目を通す楽譜が増え、拍子を外すと曲全体が遅くなります。誰かが楽譜を1枚探しに倉庫(DB)へ行ってしまうと、全員がその人を待つことになります。
1ティックの処理がバジェットを超えるとサーバーのティック周期が延び、そのエリア全体がゆっくり進んだりカクついたりします。
なぜ: 1ティック(例:50ms)で処理する仕事がバジェットを超える → すると: 1秒に20回計算するはずのゲーム状態を8回しか計算できない → 画面では: そのエリア全体がスローモーション(サーバーの設計によってはカクつき)、スキルの反応が遅い
症状: スローモーション, 入力遅延, カクつき · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
誰が誰を見られるかを全員同士で比較すると、人数が10倍になったとき計算は100倍になります。
なぜ: すべてのキャラクター同士で距離を比較しているか、グリッドに分割していても1つのセルの周辺に数百人が集中 → すると: 100人なら約1万回、1,000人なら約100万回の比較 → 画面では: ワールドボスや攻城戦のように人が集中した場所でティック時間が急増し、スローモーション・カクつき
症状: スローモーション, カクつき · 主担当 ゲーム開発チーム・サーバー開発
1人の動きを、その人が見えている全員に送ると、集まった人数の2乗に比例する数の更新を送ることになります。
なぜ: 1人の変化を、それが見える全員に送信 → すると: 1,000人が互いを見ていると、ティックごとに100万個の更新 → 画面では: 送信キューと帯域幅が飽和して遅延・パケットロス(入力遅延・早送り・ワープ)
症状: 入力遅延, ワープ, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
エリアごとに1つのスレッドが担当する構造では、1か所に人が集中すると、そのコア1つだけが100%になります。
なぜ: 1つのエリア(チャンネル)を1つのスレッドが担当 → すると: 人が1か所に集中するとそのコアだけが飽和し、ほかのコアには余裕がある → 画面では: そのエリアだけラグが出て、ほかのエリアは問題ない
症状: スローモーション, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
複数のスレッドが同じデータを使うために1つのロックを待つと、スレッドを増やしても一度に1つずつしか実行されません。
なぜ: 取引所・ギルド倉庫のような共有データを、複数のスレッドが同時に使用 → すると: ロックを取ったスレッドが終わるまで、ほかのスレッドは待機 → 画面では: 特定の機能だけ遅い、ひどい場合は全体のティックが遅延
症状: 入力遅延, フリーズ · 主担当 ゲーム開発チーム・サーバー開発
2つのスレッドが互いに相手の取ったロックを待つと、永遠に止まったままになります。
なぜ: スレッドAはロック1を取ったままロック2を、Bはロック2を取ったままロック1を待つ → すると: 両方とも永遠に止まり、関連するスレッドも次々に止まる → 画面では: サーバー全体が停止し、ウォッチドッグによる再起動で全員が切断
症状: フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発
ティックの途中でDBの応答やファイルの書き込みを待つと、その時間だけサーバーのゲーム進行全体が止まります。
なぜ: ティック内でDBの参照・保存、ログの書き込み、外部APIの呼び出しを待つ → すると: DBに100msかかればティックも100ms止まる → 画面では: DB・ディスクが遅くなるたびに、フィールド全体が一瞬止まる
症状: フリーズ, カクつき · 主担当 ゲーム開発チーム・サーバー開発
リクエストが処理速度より速く届いてキューにたまると、後ろのリクエストは数秒後にやっと処理されるか、破棄されます。
なぜ: リクエストが処理速度より速く到着 → すると: キューが長くなり、上限を超えると破棄 → 画面では: スキル・取引の反応が遅れるか、不発になる
症状: 入力遅延, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発
すべてのモンスターのリスポーン、すべてのバフの期限切れ、毎正時の報酬が同じティックに集中すると、そのティックだけ処理が数十倍重くなります。
なぜ: リスポーン・期限切れ・報酬・オートセーブのタイマーが同じ時刻にそろっている → すると: その1ティックに普段の数十倍の処理 → 画面では: 決まった時刻になるたびに一瞬止まる
症状: フリーズ, カクつき · 主担当 ゲーム開発チーム・サーバー開発
数百体のモンスターが同時にプレイヤーを追いかけて経路を計算すると、CPUを大きく消費します。
なぜ: まとめ狩りや大量スポーンで、モンスターが一斉にプレイヤーを追跡 → すると: モンスターごとに経路探索を計算 → 画面では: その狩場だけスローモーション
症状: スローモーション · 主担当 ゲーム開発チーム・サーバー開発
送るデータをバイト列に変換して圧縮するのにもCPUを使い、人が多いとこのコストが急増します。
なぜ: 更新のたびに構造体をバイト列に変換・圧縮 → すると: 人数の2乗に比例してコストが増加 → 画面では: 送信が遅れて入力遅延
症状: 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発
未処理のエラーでサーバープロセスが落ちると、そのサーバーにいた全員が同時に切断されます。
なぜ: 存在しない対象を参照するエラー(null参照)、不正なデータ、メモリ不足などの致命的なエラー → すると: サーバー(またはゾーン)のプロセスが終了 → 画面では: 全員が同時に切断、最後の保存以降の進行はロールバックされることがある
症状: 切断, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
処理を担うワーカースレッドがすべて遅い処理に塞がれると、新しいリクエストはいつまでも待たされます。
なぜ: ワーカースレッドが外部API・DBの応答待ちで塞がる → すると: 新しいリクエストに割り当てるスレッドがない → 画面では: ログイン・ショップなど特定の機能が無限ロード
症状: 接続不可・無限ロード, 入力遅延, フリーズ · 主担当 ゲーム開発チーム・サーバー開発
バグで1ティックが終わらないとサーバーが止まり、ウォッチドッグが強制的に再起動します。
なぜ: 誤った条件でループが終わらない、または再帰が暴走 → すると: ティックが終わらずサーバーが停止 → 画面では: フリーズの後、全員が切断
症状: フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発
数百人が1体のボスを同時に攻撃すると、そのボス1体の計算が1か所に集中し、ヒット情報が見ている全員に送信されます。
なぜ: 数百人が1体のボスにスキル・バフ・デバフを絶え間なく使用 → すると: ボスのHP・ヘイトリスト・デバフの計算が1か所に集中し、ヒットのたびにダメージ数値・エフェクトのパケットを見ている全員に送信 → 画面では: スキルの反映が遅れ、ダメージ数値がまとめて表示される、ボスの周辺だけスローモーション
症状: 入力遅延, 早送り, スローモーション · 主担当 ゲーム開発チーム・サーバー開発
人でいっぱいの街にテレポートすると、サーバーは新たに見えるようになった数百人の外見・装備・状態を一度に送らなければなりません。
なぜ: テレポート・ログイン・チャンネル移動で、混雑した場所に突然現れる → すると: 数百人分の全情報を一度に作って送り、自分のPCも一度に読み込む → 画面では: 到着直後に一瞬止まる、キャラクターが遅れて1体ずつ現れ、入力の反応が遅い
症状: フリーズ, 入力遅延, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
消えるはずの地面のアイテム、召喚物、終わったタイマーが片付けられずにたまると、サーバーを長く稼働させるほど毎ティックの処理が増えます。
なぜ: 地面のアイテム・召喚物・期限切れのタイマー・空のパーティ情報が、本来のタイミングで削除されない → すると: ティックごとに走査するリストが日ごとに長くなる → 画面では: メンテ明けは問題ないが、数日たつとそのサーバー・エリアだけ次第に重くなる
症状: スローモーション, カクつき, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発
新しいコンテンツ・エフェクト・同期項目がパケットのサイズと頻度を増やすと、問題なく動いていたサーバーがアップデート後からMTU・帯域幅・パケット数の上限に引っかかります。
なぜ: アップデートで新しいスキルエフェクト・同期項目・アイテム情報が増え、パケットが大きくなるか頻繁になる → すると: 大きなパケットはMTUを超えてフラグメント化され、増えた分は帯域幅・クラウドのPPS上限・送信バッファに引っかかる → 画面では: アップデート直後から、混雑した場所でワープ・スキル不発・入力遅延。インフラは何も変えていないのにパケットロスが増える
症状: ワープ, 不発・ロールバック, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・ネットワークインフラ
サーバーが覚えているすべてのもの、つまりキャラクター・モンスター・アイテム・マップはメモリに載っています。メモリ自体は速いのですが、GC(使わなくなったメモリの回収)で止まったり、少しずつ漏れたり(リーク)、足りなくなってスワップ(メモリの一部をディスクに移すこと)が起きたりした瞬間にラグになります。
Java・C#・Goのようにメモリを自動で管理する言語では、使い終わったメモリをガベージコレクター(GC)が集めて回収します。GCの方式によっては、すべてのスレッドを一瞬止めることもあります。ヒープ(プログラムが実行中に割り当てを受けて使うメモリ領域)全体を一度にGCすると、生きているデータが多いほど時間がかかり、数百msから数秒に達します。ZGCのような最新のGCは、停止を1ms未満に抑える代わりにCPUとメモリを多く使います。C++のサーバーにはGCがありませんが、解放し忘れたメモリがたまるリークや、空き領域が細かく分かれて大きなかたまりを使えなくなる断片化に悩まされます。GCがあっても、使い終わったオブジェクトをどこかで参照し続けていれば、同じようにリークが起きます。
メモリが遅くなるもう1つの理由はメモリ階層(CPUからどれだけ離れた記憶装置か)です。CPUのすぐ横のキャッシュは1ns、RAMは100ns、ディスクに追い出したメモリ(スワップ)を読み戻すとRAMの1,000倍以上かかります。下の「数字の感覚」の表で、この差を人間の時間に引き延ばしてみてください。
メモリは料理人の作業台です。手の届くところ(キャッシュ)に材料があれば速く、冷蔵庫(RAM)まで行くと少し遅くなり、作業台がいっぱいで材料を倉庫(ディスク、スワップ)に置いていると、取り出すたびにかなり時間がかかります。洗い物(GC)をしている間は料理を止めなければなりません。
Java・C#のサーバーがガベージを回収するために全スレッドを止めている間(stop-the-world)、サーバー全体が止まります。
なぜ: ヒープが埋まってGCが始まる → すると: 全ゲームスレッドを止めて回収(生存データが多いほど長引く) → 画面では: サーバー上の全員が同時にフリーズし、その後早送り
症状: フリーズ, 早送り · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
C++のサーバーでも、クエスト・AI・スキルをLuaなどのスクリプトで動かしていると、スクリプトエンジンのGCが走っている間そのゾーンが止まります。
なぜ: ゾーンごとにスクリプトエンジンがクエスト・AI・イベントを実行し、一時オブジェクトを大量に生成 → すると: スクリプトエンジンのGCが一度に大量に回収すると、そのゾーンのティックが止まる → 画面では: 特定のゾーン・特定のイベント中だけ周期的に一瞬止まる
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・サーバー開発
イベント中に一時オブジェクトを大量に生成すると、GCが普段よりはるかに頻繁に走ります。
なぜ: アイテムドロップ・戦闘ログ・イベント報酬で一時オブジェクトが急増 → すると: GCが数倍の頻度で走り、まだ破棄されていなかったオブジェクトがOld領域に移ってFull GCも早まる → 画面では: イベント時だけ周期的に一瞬止まる
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・サーバー開発
解放されないメモリが少しずつたまり、数日後にGCの多発・スワップ・強制終了につながります。
なぜ: ログアウトしたキャラクターの情報・イベントハンドラーが解放されない → すると: 数日かけて空きメモリが減っていく → 画面では: メンテ明けは正常、日を追うごとにラグが増え、最後はサーバーダウン
症状: スローモーション, フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
生存データがヒープの上限に近づくと、GCが走っても回収できるものがほとんどなく、GCが休みなく繰り返されます。
なぜ: イベントでの人数増加やリークで、生存データがヒープの上限近くまで埋まる → すると: GCがわずかしか回収できず、すぐにまたFull GC、CPUの大半をGCが使う → 画面では: サーバー全体が数分間スローモーション・フリーズを繰り返し、メモリ不足で終了
症状: スローモーション, フリーズ, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
メモリが足りずOSが一部をディスクに退避させると、そのメモリを使うたびに1,000倍以上遅いディスクを待つことになります。
なぜ: 使用メモリが物理RAMを超える → すると: OSが一部をディスクに退避させ、必要なときに読み戻す → 画面では: ティックが数百msに跳ね上がり、サーバーの全ユーザーがスローモーション・フリーズ
症状: スローモーション, フリーズ · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
データがメモリのあちこちに散らばっていると、CPUが毎回遅いRAMまで取りに行って待つことになります。
なぜ: オブジェクトがポインターでつながって散らばり、順不同にアクセス → すると: CPUキャッシュにないので毎回RAMから読む(100倍前後遅い) → 画面では: 同じ処理でもティックのコストが数倍、ひどいとスローモーション
症状: スローモーション · 主担当 ゲーム開発チーム・サーバー開発
アロケーションと解放を繰り返して空き領域が細かく分断されると、実際に使っている量よりはるかに多くのメモリを占有するようになります。
なぜ: サイズがまちまちのメモリを、複数のスレッドが長期間アロケーション・解放 → すると: 空き領域が細かく散らばってOSに返せず、使用量がリークのように増え続ける → 画面では: 長く稼働するほどスワップ・メモリ不足で遅くなり、最後は強制終了
症状: スローモーション, 切断 · 主担当 ゲーム開発チーム・サーバー開発
CPUが2つあるサーバーで、反対側のCPUにつながったメモリを使うとアクセスが遅くなります。
なぜ: スレッドとメモリが別々のCPUソケットに配置される → すると: メモリアクセスが遅くなる(機器によって1.5〜2倍) → 画面では: 同じスペックなのにプロセスごとに性能差
症状: スローモーション · 主担当 インフラチーム・サーバーインフラ
ログ、キャラクターの保存、マップデータ、DBファイルはすべてディスクにあります。ディスクはメモリより数百倍(SSD)から10万倍(HDD)も遅いので、ゲームサーバーがディスクを待つ構造なら、ディスクが忙しくなった瞬間にゲームも一緒に止まります。
ディスクの性能は「1秒に何回読み書きできるか」(IOPS)で測ります。古いHDDは150回ほど、SSDは数万〜数十万回です。クラウドのディスクは支払った料金に応じて上限が決まります(AWSのgp3は標準で3,000回)。一部のクラウドディスクや小さなサーバースペックは、ふだんの速度に加えて一時的にさらに高い性能を出せるバーストクレジットを与えますが、忙しい時間が長引くとクレジットが尽きて速度が急に落ちます。「毎晩、数時間たつとラグが出る」という報告がこの形です。
ポイントは誰が待つかです。ふつうのファイル書き込みは、OSがいったんメモリで受け取っておき、後でディスクに書き出すため、たいていすぐ終わります。問題になるのは、「ディスクに実際に書き込まれるまで」待つよう指示したとき(fsync)や、OSがメモリで受け取っておける上限に達したときです。このときゲームスレッドが自分で待つと(同期)、ディスクが100ms遅れればティックも100ms止まります。書き込みを別スレッドに任せれば(非同期)ゲームは止まりませんが、サーバーが突然落ちると、まだ書き込めていない内容が消えることがあります(不発・ロールバック)。
ディスクは倉庫、IOPSは倉庫の扉の数です。扉が少なければ、物を出し入れする人が列を作ります。バーストクレジットは短い間だけ全力疾走できる体力で、使い切ると歩く速さに戻ります。
ゲームスレッドがログを1行書くたびにディスクへの書き込み完了を待っていると、ディスクが忙しいときにゲームの進行も一緒に止まります。
なぜ: 戦闘・取引ログをゲームスレッドから直接ファイルに書く → すると: 確実な書き込み(fsync)を要求したり、OSの書き込みバッファ(ページキャッシュ)が上限に達したりすると、ディスクが忙しいときに1回の書き込みが数十ms → 画面では: ログの多い戦闘で一瞬止まる
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
データを「確実に」ディスクに書き込むよう要求すると、ディスクによっては1回に0.1ms〜数十msかかり、要求が集中するとキューが長くなります。
なぜ: 定期保存・ログアウトラッシュで確実な書き込みの要求が集中 → すると: ディスクのキューが長くなる → 画面では: 保存のタイミングごとにラグ、ログアウト・チャンネル移動の遅延
症状: カクつき, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, インフラチーム・DBインフラ
一部のクラウドディスクや小さなサーバースペックには、一時的にベースラインより速く使えるバーストクレジットがあります。忙しい時間が長引いてクレジットが底をつくと、速度が急に落ちます。
なぜ: ベースライン性能を超えて長時間使用 → すると: バーストクレジットが底をつき、ベースライン性能まで急落 → 画面では: 毎晩、数時間たったころからラグが出始める
症状: カクつき, スローモーション, 入力遅延 · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ
ディスクが1秒間に処理できる要求数を超えると、キューが長くなって遅延が急増します。
なぜ: 読み書きの要求がディスクの処理能力に近づく → すると: キューが長くなる(たいてい利用率90%以上で急増) → 画面では: 保存・ロードの遅延、同期呼び出しならフリーズ
症状: 入力遅延, フリーズ · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発, インフラチーム・DBインフラ
ログとダンプがたまってディスクがいっぱいになると書き込みが失敗し、備えがなければサーバーが落ちます。
なぜ: ログ・ダンプ・一時ファイルがたまって100% → すると: 書き込み失敗。エラー処理がなければクラッシュ、あれば保存失敗 → 画面では: 切断、進行状況のロールバック
症状: 切断, 不発・ロールバック · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ, ゲーム開発チーム・サーバー開発
深夜のバックアップ、ログの圧縮、セキュリティスキャンがディスクを独占すると、ゲームサーバーの読み書きが詰まります。
なぜ: スケジュールされたバックアップ・圧縮処理が始まる → すると: ディスクの帯域幅とIOPSの大半を占有 → 画面では: 毎日同じ時刻にラグ
症状: カクつき, 入力遅延 · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ
サーバーがダンジョン・マップのデータを初めて要求されたときにディスクから読むと、そのティックの間、全員が止まります。
なぜ: 誰かが初めてダンジョン・エリアに入場 → すると: サーバーがゲームスレッドでデータをディスクから読む → 画面では: そのサーバーの全員が一瞬フリーズ
症状: フリーズ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
サーバーが落ちるときに数GBのメモリをディスクに書き出すため、再起動が数分遅れることもあります。
なぜ: サーバーのクラッシュでメモリ全体をファイルに書き出す → すると: 数GBを書き込む間は再起動できない → 画面では: サーバーが落ちて切断された後、しばらく接続できない
症状: 接続不可・無限ロード · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
HDDはヘッドがプラッタ上を移動する(シーク、seek)必要があるため、散らばったデータの読み書きに1回あたり10ms近くかかります。
なぜ: 古いサーバーや低価格ストレージでHDDを使用 → すると: ランダムな読み書きのたびに約10ms → 画面では: 全体的な保存・ロードの遅延
症状: 入力遅延 · 主担当 インフラチーム・サーバーインフラ · 副担当 インフラチーム・DBインフラ, ゲーム開発チーム・サーバー開発
キャラクター、アイテム、ゲーム内通貨、取引記録のように、絶対に失ってはいけないものが入っている場所です。DBが遅くなると、戦闘は問題ないのにアイテムの反映が遅れ、取引が失敗し、ログインが終わらなくなります。ゲームサーバーがDBを待つ構造なら、フィールド全体が止まります。
ゲームサーバーはDBとあらかじめいくつかの接続(コネクションプール)を張っておき、使い回します。クエリ(DBに送る要求)1つに時間がかかると、そのコネクションが使用中のままになり、プールのコネクションがすべて使用中になると、残りの要求はキューで待ちます。クエリが遅くなるよくある理由は2つです。インデックス(本の索引)がなくてテーブル全体を読む(フルスキャン)か、複数の要求が同じ行を同時に更新しようとしてロックを待つかです。
DBは信頼性を保ち、多くの要求を受けるために、いくつもの仕組みを使います。読み取りを分担するレプリカ、障害時に切り替わる予備のDB、変更分を定期的にまとめてディスクに書き込むチェックポイント。チェックポイントが集中すると一時的に遅くなります。レプリカが遅れると「さっき買ったアイテムが見えない」、レプリケーションが遅れたまま予備のDBに切り替わると「接続したら少し前の状態に戻っていた」といった不発・ロールバックの症状が起きます。ゲームサーバーがキャラクターを数分に1回しか保存しないなら、サーバーが落ちたときに「10分前に戻った」ことになります。
DBは銀行の窓口です。窓口の数(コネクションプール)は決まっていて、1つの要求が帳簿全体をひっくり返して探す作業(フルスキャン)をすると、後ろの要求がすべて待たされます。全員が同じ金庫(ホットスポット)を開けようとすると、1人ずつしか入れません。
インデックスがないと、条件に合う行を探すためにテーブル全体を読む必要があります(フルスキャン)。
なぜ: 新機能のデプロイで、インデックスのない条件検索が追加される → すると: 数百万行をすべてスキャンし、クエリ1つに数百ms〜数秒 → 画面では: 郵便受け・取引履歴のロード遅延、コネクションがふさがって他の要求まで待たされる
症状: 入力遅延, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
全員が同じ行(ギルド倉庫、オークションの人気アイテム、サーバー全体のカウンター)を更新しようとすると、ロックを取れるのは1人ずつです。
なぜ: イベント・人気アイテムで同じ行に更新が集中 → すると: ロックを取れるまで要求が待たされる → 画面では: 取引失敗、「しばらくしてからもう一度お試しください」、タイムアウト
症状: 不発・ロールバック, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
2つのトランザクション(ひとまとまりで処理されるDB操作)が互いに相手のロックした行を待つと、DBが片方を強制的に取り消します。
なぜ: 取引Aはアイテム→通貨、Bは通貨→アイテムの順にロック → すると: DBがデッドロックを検知して片方をロールバック → 画面では: 取引・製作がときどき失敗、アイテムが元に戻る
症状: 不発・ロールバック, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
DBとの接続数は決まっているため、遅いクエリが接続を占有すると、残りの要求は待たされます。
なぜ: 遅いクエリや要求の殺到で、すべての接続が使用中 → すると: 新しい要求は接続が空くまで待つ → 画面では: ログインの無限ロード、保存の遅延、タイムアウト
症状: 接続不可・無限ロード, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
書き込みはプライマリに、読み込みはレプリカから行う構成で、レプリカの追従が遅れると、書いたばかりの内容が見えません。
なぜ: プライマリに書き込みが集中し、レプリカが数秒遅れる → すると: 保存したばかりの内容をレプリカから読むと、まだ反映されていない → 画面では: 買ったばかりのアイテムが表示されない、取引所の価格が古い値のまま、重複付与のバグ
症状: 不発・ロールバック · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
DBがメモリ上の変更分を定期的にまとめてディスクに書き込む瞬間、クエリが遅くなります。
なぜ: 変更分がたまり、定期的にディスクへ書き出す → すると: その瞬間ディスクの負荷が上がり、クエリが遅延 → 画面では: 定期的に保存・ロードが遅くなる
症状: 入力遅延, カクつき · 主担当 インフラチーム・DBインフラ
DBを再起動するとメモリ上のキャッシュが空になっているため、しばらくはすべての読み込みがディスクから行われます。
なぜ: メンテナンスでDBを再起動 → すると: よく使われていたデータがメモリになく、ディスクから読む → 画面では: メンテ明けしばらくログイン・ロードが遅い
症状: 接続不可・無限ロード, 入力遅延 · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
キャラクター1体を読み込むたびに数十回の個別クエリを発行していると、数万人の同時ログインは数百万件のクエリになります。
なぜ: キャラクターのロード時にアイテム・スキル・クエストを個別にクエリ → すると: メンテ明けの同時ログインでクエリが急増 → 画面では: ログインの無限ロード、プレイ中のユーザーの保存まで滞る
症状: 接続不可・無限ロード, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ランキング集計、郵便の一括送信、古いデータの整理をサービス中に実行すると、ロックとディスクを占有します。
なぜ: サービス時間中に大量の処理を実行 → すると: 広い範囲のロック、ディスク・CPUの占有 → 画面では: 特定の時間帯に取引・保存が失敗、ロード遅延
症状: 入力遅延, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
プライマリが落ちてスタンバイDBに切り替わる間は書き込みができず、レプリケーションが間に合わなかった最後のデータは失われることがあります。
なぜ: プライマリの障害でスタンバイDBが昇格 → すると: 切り替え中は数秒〜数分書き込み不可、非同期レプリケーションならレプリカに届いていないデータが失われる可能性 → 画面では: 一時的にすべての保存が失敗、アイテム・経験値のロールバック
症状: 不発・ロールバック, フリーズ, 切断, 接続不可・無限ロード · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
負荷を減らすために数分に1回しか保存しないと、その間にサーバーが落ちた場合に進行状況が失われます。
なぜ: キャラクターの状態を数分ごとに1回保存 → すると: その間にサーバーのクラッシュ・障害が発生 → 画面では: 再接続すると数分前の状態(ロールバック)
症状: 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
人気データのキャッシュが同時に期限切れになると、数千件の要求が一斉にDBへ殺到します。
なぜ: Redisなどに保存した人気データが同時に期限切れ → すると: 同じデータを作り直そうとする要求が一斉にDBへ殺到 → 画面では: DBの過負荷で複数の機能が次々に遅くなったり止まったりする
症状: 入力遅延, フリーズ, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
1つのトランザクションが長く開いたままだと、ロックを持ち続けるうえ、DBが古いバージョンのデータを整理(purge)できないため、全体が徐々に遅くなります。
なぜ: トランザクションを開いたまま別サーバーの応答を待つ、またはサービス中にプライマリで長い集計クエリを実行 → すると: 取ったロックが解放されず、整理すべき古いバージョンのデータがたまり続ける → 画面では: その行を使う機能がタイムアウト、数時間かけて保存・読み込みが全体的に遅くなる
症状: 入力遅延, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
Redisはコマンドを1つずつ順番に処理するため、遅いコマンドが1つあると、その後ろのすべての要求が止まります。
なぜ: サービス中にKEYSで全件検索、要素が数百万個あるランキング・リストを丸ごと読んだり削除したりする → すると: そのコマンドが終わるまで、他のすべての要求が待たされる(数十ms〜数秒) → 画面では: セッション・ランキング・キャッシュを使う機能が一斉に一瞬止まる、ログイン遅延
症状: フリーズ, 入力遅延, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
コードは変わっていないのに、DBが同じクエリの処理方法(実行計画)を変えると、昨日2msだったクエリが今日は数百msになります。
なぜ: 統計情報の自動更新、DBの再起動、データ分布の変化で、DBが実行計画を立て直す → すると: インデックスを使わない計画が選ばれ、同じクエリが数十〜数百倍遅くなり、コネクションがふさがる → 画面では: デプロイもなかったのに特定の機能のロードが急に遅くなり、他の要求まで待たされる
症状: 入力遅延, 接続不可・無限ロード · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
サービス中にテーブルへカラムやインデックスを追加すると、一瞬だけ必要なロック1つのために、そのテーブルを使うすべての要求が待たされることがあります。
なぜ: ホットフィックスでサービス中のテーブルにカラム・インデックスを追加 → すると: スキーマ変更が先に開いていた長いトランザクションを待ち、後から来るすべての要求はそのスキーマ変更を待つ → 画面では: そのテーブルを使う機能(インベントリ、郵便など)が丸ごと止まり、タイムアウト
症状: 入力遅延, 不発・ロールバック, 接続不可・無限ロード · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
最近のMMOはたいてい、ログイン、ゲートウェイ、フィールド、ダンジョン、チャット、パーティ、オークション、キャッシュ、DBの各サーバーが互いに呼び出し合って動く構成です。1か所で障害が発生するとつながった先へ広がり、デプロイ・スケーリング・メンテナンスといった運用作業もラグを生みます。
サーバーを分けると、1か所の障害が全体に広がるのを防げますが、その代わりに呼び出しチェーン(サーバーが別のサーバーを順に呼び出すつながり)が生まれます。ゲームサーバーがオークションサーバーを呼び、オークションサーバーがキャッシュとDBを呼ぶ、という具合です。チェーンの末端のサーバーが遅くなると、手前のサーバーは応答を待ちながらスレッドとコネクションを占有し続け、最後には関係なさそうな機能まで止まります。これをカスケード障害といい、タイムアウトとサーキットブレーカー(失敗が続く呼び出しをしばらく遮断する仕組み)で広がりを防ぎます。
運用作業もラグの原因です。アップデートのデプロイ中の再起動、人が集中したときにサーバーを自動で増やすまでにかかる数分、ゾーン移動時にキャラクターを別のサーバーへ移す処理、ボットやマクロが生む目に見えない負荷は、どれもプレイヤーには「ラグ」に見えます。
サーバー構成は複数の部署が決裁を回し合う会社です。決裁ルートの末端の部署(DB)が1つ遅くなると、手前の部署は書類を持って列を作り、最後には会社全体の業務が止まります。タイムアウトは「10分以上返事がなければいったん差し戻す」ルールで、ブレーカーは「差し戻しが続いたら、しばらくその部署には書類を送らずにすぐ返す」ルールです。
クライアントとゲームサーバーの間に中継サーバーを置くと、経由するたびに処理時間が加わり、そのサーバーが単一障害点になります。
なぜ: クライアント ↔ ゲートウェイ ↔ ゲームサーバーの構成 → すると: 中継サーバーでの処理・待ちが加わり、過負荷になると全員に影響 → 画面では: 全体のPingが上昇、ゲートウェイ障害時はそこを経由するユーザー全員が切断
症状: 入力遅延, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
別のエリアやダンジョンに入るとき、キャラクター情報を別のサーバーへ引き渡す過程で遅延や失敗が起きます。
なぜ: ダンジョン入場や大陸移動で担当サーバーが変わる → すると: 保存 → 転送 → 読み込み、移動先サーバーが混雑しているか空いているダンジョンインスタンスがなければ待機 → 画面では: 長いロード、入場失敗、移動中の切断
症状: 接続不可・無限ロード, フリーズ, 切断, 引き戻し · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
1つのサービスが遅くなると、それを呼び出すサーバーが応答待ちで塞がり、関係のない機能まで止まります。
なぜ: DB・認証など1つのサービスが遅くなる → すると: 呼び出し側サーバーのスレッドと接続が応答待ちで塞がり、失敗したリクエストの再試行が負荷を上乗せ → 画面では: 関係なさそうな機能まで、すべて遅くなるか止まる
症状: フリーズ, 入力遅延, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
チャット・パーティ・オークションのように、ゲームサーバーとは別に動くサーバーで障害が起きると、その機能だけが動かなくなります。
なぜ: 機能専用サーバーが遅くなるか落ちる → すると: その機能のリクエストだけ応答なし → 画面では: チャットができない、パーティ招待に反応なし、取引所が無限ロード(戦闘は正常)
症状: 不発・ロールバック, 接続不可・無限ロード · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
アップデートのためにサーバーを再起動するとき、接続を移さずに止めると、そのサーバーにいた人は切断され、終了直前の保存と再接続が一気に集中します。
なぜ: ホットフィックスのデプロイでサーバーを順番に再起動 → すると: 接続を別のサーバーに移さずに終了、そのサーバーにいた全ユーザーの保存がDBに集中 → 画面では: 告知なしの切断、再接続の殺到
症状: 切断, 接続不可・無限ロード, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
人が集中するとサーバーを自動で増やしますが、準備に数分かかり、その間は既存のサーバーが過負荷になります。
なぜ: イベント開始で接続が急増 → すると: 新しいサーバーが起動して準備が整うまで数分 → 画面では: イベント開始直後の数分間、スローモーション・接続不可
症状: スローモーション, 接続不可・無限ロード · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
障害が起きるとログが急増し、ログを同期で送るサーバーはログのせいでさらに遅くなります。
なぜ: エラー発生に伴い、ログ・メトリクスの送信量が急増 → すると: ログコレクターが詰まり、同期送信するサーバーは待たされる → 画面では: 障害時のカクつき・フリーズがログのせいでさらに悪化
症状: カクつき, フリーズ · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・サーバーインフラ
サーバーごとに時計が少しずつずれていると、クールタイム・バフ・イベント開始の判定がサーバーごとに食い違います。
なぜ: 時刻同期が止まったサーバーの時計が、ほかのサーバーと数百ms〜数秒ずれる → すると: バフの終了時刻のような絶対時刻をサーバー間で受け渡すと判定が食い違う → 画面では: 移動したらバフが消える、クールタイムがまた最初から始まる
症状: 不発・ロールバック · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ボットは人よりはるかに頻繁にリクエストを送り、サーバーのスループットを食いつぶします。
なぜ: 狩り・移動・取引を休まず繰り返すボットが大量に接続 → すると: サーバーの処理量とDB負荷が増加 → 画面では: 特定の狩場やサーバー全体が重くなる(スローモーション・入力遅延)
症状: スローモーション, 入力遅延 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・ネットワークインフラ
プラットフォームのログイン、決済、本人確認などの外部サービスが遅くなったり止まったりすると、その段階で先に進めなくなります。
なぜ: 外部の認証・決済サービスの障害や遅延 → すると: その段階で応答待ち → 画面では: ログイン不可、決済失敗。すでにプレイ中の人は問題なし
症状: 接続不可・無限ロード, 不発・ロールバック · 主担当 外部・外部 · 副担当 ゲーム開発チーム・サーバー開発
近いリージョンがあるのに遠いリージョンのサーバーに割り当てられると、回線に問題がなくても、そのユーザーだけPingが常に高くなります。
なぜ: GeoIPデータの誤り、VPN、パーティメンバーの平均Pingでパーティ全体を割り当て、人数が足りないときに遠いリージョンまで広げるルール、DNSリゾルバーの位置を基準にした割り当て → すると: 近いリージョンがあるのに、海の向こうのリージョンのサーバーに接続 → 画面では: 複数のリージョンにサーバーを置いたゲームで、自分だけ(または自分のパーティだけ)Pingが常に高く、入力遅延・引き戻し・スキル不発
症状: 入力遅延, 引き戻し, 不発・ロールバック · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・ネットワークインフラ, 外部・外部
ログイン・API・アップデートサーバーの証明書が期限切れになったり中間証明書が抜けていたりすると、その瞬間から新たに接続するクライアントのTLS接続が失敗します。
なぜ: 証明書の有効期限が切れている、サーバーが中間証明書を含めずに送っている、またはユーザー端末の日付・時刻がずれている → すると: クライアントが証明書の検証に失敗し、TLS接続を切断 → 画面では: ログイン・アップデートの段階で接続不可・無限ロード、ショップなどHTTPSの機能だけ失敗。すでに接続していた人はたいてい問題なし
症状: 接続不可・無限ロード, 不発・ロールバック · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
リリース直後やメンテ明けに接続が集中すると、ログイン待機列が上限に達して新たな待機を拒否し、待っていたユーザーは一瞬切れた間に順番を失って最後尾に戻されます。
なぜ: ログインサーバーが一度に受け付けられる人数より接続しようとする人が多いため待機列を設け、長くなりすぎるとサーバーを守るために新たな待機を拒否 → すると: 待機列が長いほど待ち時間が延び、その間にWi-Fi・モバイル回線が一瞬途切れただけで順番を失う → 画面では: 接続不可・無限ロード、待機中にエラーが出てゲームが終了、また最後尾から待ち直し
症状: 接続不可・無限ロード, 切断 · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発, インフラチーム・サーバーインフラ
ラグ報告を受けたら、「誰に、いつ、どんな形で」の3つだけを選んでみてください。この白書に載っている原因のうち、よく当てはまる候補をスコア順に表示します。確定診断ではありませんが、どのチームに最初に問い合わせるかを決めるには十分です。
報告やアラートが来たら、範囲 → 時点 → 階層の順に絞り込みます。異常がどこに集中しているかで担当が最も大きく分かれ、何と重なったかで原因が絞られ、どの階層のメトリクスが異常かで確かめます。原因カードごとにある「グラフでは」と「確認方法」をあわせて使えば、グラフの形で候補を選び、確認箇所をすぐに見つけられます。
異常がどこに集中しているか
何と重なっているか
どの階層のメトリクスが異常か
| 確認するもの | こう見えたら | 最初に呼ぶ担当 |
|---|---|---|
| サーバーのソケット受信キュー(Recv-Q) | サーバープロセスが時間内に読み出せずにたまる | ゲーム開発チームサーバー(ティックの停止・GC・ロック) |
| 接続ごとの再送・RTT | 一部の接続だけ、特定のASNに集中 | インフラチームネットワーク 外部通信事業者・ユーザーの回線 |
| 1台のホストのすべての接続 | インフラチームサーバー機器・OS(NIC・カーネル) | |
| アップデート直後にサーバー全体で再送・帯域幅が増加 | パケットのサイズ・頻度が変わった | ゲーム開発チームサーバー インフラチームネットワーク(MTU・上限) |
| CPUスチール・スロットリング・softirq・NICでの破棄 | 増加 | インフラチームサーバー機器・OS |
| 1スレッドだけ100%、ランキュー遅延、GC停止 | 増加 | ゲーム開発チームサーバー |
| DBの遅延が増加、クエリ数は変わらない | IOPS・ロック・ほかのジョブ | インフラチームDBサーバー |
| DBのクエリ数・パターンがアップデート後に変わった | N+1、新しいクエリ | ゲーム開発チームサーバー |
| 海外拠点からの外形監視(RTT・パケットロス) | 悪い | インフラチームネットワーク 外部通信事業者 |
| 外形監視は正常なのにユーザーだけ悪い | ユーザーの環境、またはクライアント | 外部ユーザーの環境 ゲーム開発チームクライアント |
| 切断理由の分布 | ハートビートのタイムアウト↑ / RST↑ / サーバーによる切断↑ | NAT・経路 / 機器 / サーバー |
| 正確な周期(正時、N分) | 定期ジョブ・バックアップ・GC・イベント | そのスケジュールを組んだ担当 |
監視グラフがどんな形かがわかるだけでも、候補は大きく減ります。以下の13種類の形ごとに、その形を生む原因を集めました。原因カードの小さな図も同じ形です。実線は主に見るメトリクス、点線はあわせて見るメトリクス(人数、待ち・エラーなど)、薄い点線は平常時の水準です。
普段は低く、数秒・数分ごとや毎正時のように同じ間隔で跳ね上がります。
クライアントのガベージコレクション, ゲームのセキュリティモジュール(アンチチート)の検査, Wi-Fiのバックグラウンドスキャン, 定期実行ジョブ, タイマーの一斉発火, サーバーGCの全停止, スクリプトエンジンのGC停止, fsyncの集中, バックアップ・圧縮・スキャン処理, チェックポイント・ログフラッシュ, 大規模なバッチ処理, キャッシュスタンピード
決まった間隔なく不規則に跳ね上がり、すぐに戻ります。
フレームタイムのスパイク, 過度な外挿(デッドレコニング), クライアントサイド予測の不一致, 固定タイムステップの追いつき処理の暴走, バックグラウンドプロセスによるCPU占有, クライアントのメモリ不足・スワップ, NICの省電力・ドライバーの問題, Wi-Fiの干渉・電波の弱さ, 5G↔LTEの頻繁な切り替え(5Gエリアの境界), 回線品質の不良, リングバッファ不足, 仮想化オーバーヘッド・ノイジーネイバー, カーネルのソケットバッファ不足, CPUスチール(仮想マシン), メモリの回収・コンパクションによる停止, システム時刻のジャンプ(NTPステップ), 遅いクライアントによるブロッキング送信, 信頼性UDPの再送設定, RSTによる強制終了で最後のデータが消失, ゲームスレッドの同期呼び出し, 同期ログ書き込み, サーバーの遅延ロード, DBのデッドロック, Redisの遅いコマンド, ログ・監視の過負荷, ロックステップでの最も遅いプレイヤー待ち, ロールバックネットコードの予測失敗, タイムスタンプなしの受信即時再生, 厳しすぎるサーバー検証, コマンド同期の経路計算の不一致, 視界登録の順序の乱れ, 基準スナップショットの欠落, 消滅通知の欠落(ゴースト), オブジェクトIDの再利用による混同, 遅延の急上昇による不要な再送
アップデート・設定変更・経路変更など特定の時刻を境に一段上がり、そのまま戻りません。
海底ケーブル・国際回線の障害, BGPの経路変更・収束, DDoS対策の経由・誤検知, OS・カーネル・ドライバー・ファームウェアのアップデート後の性能変化, アップデートによるトラフィックパターンの変化, インデックスのないクエリ, 実行計画の変化によるクエリ遅延, サービス中のスキーマ変更(DDL)によるロック, 外部サービスへの依存, 経路変更・ECMPの不良経路
数時間・数日かけて少しずつ上がります。稼働時間とともに大きくなります。
時刻同期の誤差, float型で持つ時刻の精度低下, クライアントのメモリリーク, 省電力モード・サーマルスロットリング, メモリリーク, スワップ, メモリの断片化, ディスクフル, 長時間開いたままのトランザクション, サーバー間の時刻のずれ
ゆっくり上がっては、再起動・クリーンアップの瞬間にストンと落ちるのを繰り返します。
夜のピークのように、一日のうち同じ時間帯にだけ山なりに上がります。
Wi-Fiチャンネルの混雑, ピーク時間帯のピアリング混雑, 特定の通信事業者のユーザーに集中する検証の誤検知, ボトルネックでのキューあふれ(輻輳によるロス)
同時接続数や一か所に集まった人数が増えると、それを上回る勢いで上がります。
大人数の描画負荷, メインスレッドのパケット処理ボトルネック, 受信バッファのあふれ, 同じ端末の他のアプリによる帯域幅の占有, バッファブロート(ルーターのキュー), スイッチのマイクロバースト, スレッド過多とコンテキストスイッチ, コンテナのCPUスロットリング(CFSクォータ), UDPパケットのIPフラグメンテーション, ブロッキングI/O構造, ティックバジェット超過, 視界(AOI)計算の急増(N²), ブロードキャストの急増, シングルスレッドのエリア過負荷(ホットスポット), ロック競合, 経路探索の急増, シリアライズ・圧縮のコスト, 1体に集中する戦闘(ワールドボス), アロケーションの急増, ホットスポットの行ロック競合, レプリケーション遅延, ゲートウェイ・プロキシ経由, ゾーン移動(サーバー間の引き継ぎ), 接続ごとの送信バジェット・優先度, 送信バーストによる浅いバッファのあふれ, デュプレックスの不一致
スループット・接続数がある値に達するとそれ以上伸びず、そこから待ち・エラーが増えます。
ビデオメモリ(VRAM)不足, ルーターの性能不足・過熱, 通信事業者の速度制限・トラフィック管理, DDoSによる共有回線の飽和, ファイアウォールのセッションテーブル飽和, クラウドのNATゲートウェイの接続・ポート上限, データセンター回線の飽和, NIC割り込みの単一コア集中, クラウドのPPS上限超過, NIC帯域幅の飽和, ファイルディスクリプタの上限, サーバーのconntrackテーブル飽和, サーバー間接続のエフェメラルポート枯渇, メッセージキューの滞留, スレッドプールの枯渇, GCスラッシング(ヒープの空き不足), クラウドディスクのバーストクレジット枯渇, IOPS上限・キューの飽和, コネクションプールの枯渇, カスケード障害, ログイン待機列の上限・再接続猶予の不足, メモリ・VRAM不足によるストリーミングの失敗, ポリサーによる超過分の破棄, 受信サーバーのホストでのパケット破棄, ファイアウォール・接続追跡による破棄, 中間機器の処理上限超過(ファイアウォール・IPS・DDoS対策)
跳ねることなく、ずっと高い値にとどまります。距離・経路・設計など、構造に起因する場合です。
補間バッファがないか短い, V-Syncとレンダーキュー, タイマー分解能, ディスプレイ・入力デバイス・フレーム生成による遅延, 伝搬遅延(物理的な距離), 迂回ルーティング, 過剰な割り込みコアレッシング, GRO/LROの結合待ちによる遅延, サーバーの電源管理(C-state・周波数制御)による遅延スパイク, Nagleアルゴリズム+遅延ACK, キャッシュミス, HDDのシーク遅延, サーバー応答後にだけ演出(リクエスト・レスポンス方式), 逐次往復の多いプロトコル(chatty), スキルの先行入力なし, クライアント権威型, 二重のティック待ち, 低いスナップショット送信レート, 順序の入れ替わりによる不要な高速再送, RTOの設定が環境に合っていない, 中間機器によるTCPオプションの除去
大部分は正常で、特定のユーザー・地域・ISP・端末だけが高くなります。
ストレージが遅くアセットストリーミングが間に合わない, クライアントのクラッシュ, セキュリティソフトによるパケット検査, オーバーレイソフトの干渉, RRC状態遷移の遅延(モバイル無線の省電力), モバイル電波の弱さ・不感地帯, 公衆Wi-Fi・社内ネットワークの制限, 衛星インターネット(低軌道・静止軌道), ECMP経路のうち1本の不良, 国・通信事業者単位のUDP制限・パケット検査, DNSの障害・遅延, VPN・ラグ軽減ツール経由, ロードバランサーの偏り・ヘルスチェックの誤判定, ケーブル不良・ポートエラー, MTUの不一致(大きなパケットだけ消える), 遅いクライアント(slow consumer)の処理ポリシー, keepaliveのデフォルト2時間, アイドル後のスロースタート, SO_REUSEPORTの振り分けの偏り, NUMAのリモートメモリ, 大量のマクロ・ボット, マッチメイキング・リージョン割り当ての誤り, Pingに削られる短い判定の受付時間, ラグコンペンセーションのない判定, 過剰なラグコンペンセーション, ホスト(部屋主)型の構成, 先行演出後のサーバー拒否, 回線が重い人がほかの人の画面でまとめて動く, 受信即時処理のサーバーで起きる早送り, プレイヤーごとの入力バッファのサイズ, 回線が重いパーティメンバー1人とボスのギミック, モンスターの制御権が遅いクライアントにある, 特定キャラクターのデータ肥大化, チャンネル・インスタンス・フェーズの違い, ロード中に届いた出現通知の破棄, 固定UDPポートの衝突, IP・端末基準のセッション識別バグ, 多重起動の制限, キャッシュ・アセットファイルへの同時アクセスの競合, 表示オプションの違い, クライアントのバージョン・データの不一致, 時刻推定の誤差によるオブジェクトの保留, 無線区間のパケットロス, 物理エラー(不良ケーブル・光モジュール・コネクター), MTUブラックホール(大きいパケットだけ繰り返し失われる), ACKの遅れ・消失(上り回線の飽和)
しばらく受信量が0になった後、一気にまとめて届きます。
ウィンドウの最小化・非アクティブ時の処理制限, 基地局のハンドオーバー(移動中), クラウドホストのメンテナンス・ライブマイグレーション, NICドライバー・ファームウェアの問題, TCPのHOLブロッキング, TCPのRTOと指数バックオフ, バックグラウンドウィンドウの処理制限, thin streamの遅い回復, ゼロウィンドウ(再送のように見える停止)
接続数がガクッと落ちるか、切断数が一瞬で跳ね上がります。
モバイルアプリのバックグラウンド移行, Wi-Fi ↔ LTE・5Gの切り替え, NATマッピングの期限切れ, 通信事業者の共有IP(CGNAT), ロードバランサーのアイドルタイムアウト, クラウドのセキュリティグループによる接続追跡の期限切れ, ネットワーク機器のフェイルオーバー, OOM Killer, WindowsのUDPソケットのWSAECONNRESETエラー, デッドロック, サーバークラッシュ, 無限ループ・ロジックの暴走, コアダンプの書き出し, DBのフェイルオーバー, 長い保存間隔による進行状況の消失, 補助サーバーの障害, デプロイ・再起動, TLS証明書の期限切れ・設定ミス, 接続中のNAT・ロードバランサーのマッピング期限切れ
サーバーのオープンやイベント開始の直後に大きく跳ね上がり、徐々に落ち着きます。
メインスレッドでの同期ロード・シェーダーコンパイル, 接続待ちキュー(backlog)のあふれ, 密集エリア進入時のスポーン集中, コールドキャッシュ(再起動直後), ログイン殺到とN+1クエリ, オートスケーリングの遅れ, 入場直後に集中する出現情報の欠落, 接続要求(SYN)の再送
原因ごとに、最も手軽な確認手段を数えました。インフラのツールは、OS・ネットワーク・クラウド・DBのツールとランタイムの起動オプション(GCログなど)で確認できるので、ゲームのコードを変更しなくて済みます。ゲームのログ・メトリクスは、ティック時間や切断理由のように、ゲームが記録しないと見えないものです。この欄が多い層ほど、開発チームに計測を依頼する根拠になります。
平均はスパイクを隠します。1秒に20ティックのサーバーでは、ティックの1%が遅いだけでも5秒に1回ほど全員の動きが一瞬止まりますが、平均ティック時間はほとんど変わりません。そのため、パーセンタイルもあわせて確認します。p50(中央値)は半分がこれより速い値、p99は100回のうち最も遅い1回付近の値です。ユーザーが「ラグ」として記憶するのは、たいていp99のほうです。
集計間隔もスパイクを隠します。1分平均のグラフでは、1秒の停止が1/60に薄まります。停止を探すときは、同じグラフの最大値やp99、より短い間隔のグラフもあわせて確認します。
ジッターは、パケットが届く間隔がどれだけばらつくかを表します。平均のPingが低くてもジッターが大きいと、補間バッファが空になってカクつき・ワープが起きます。
| 測り方 | 何を測るか | 注意点 |
|---|---|---|
ping (ICMP) | 機器までの往復時間 | ルーター・サーバーがICMP応答を後回しにしたり数を制限したりすることがあるので、ゲームのパケットとは違う値になることがある。ブロックされていると応答がまったくない |
mtr·traceroute | 区間ごとの遅延・パケットロス | 途中の機器1台だけロスが高く、その先の区間が正常なら、その機器がICMP応答だけを減らしている可能性が高い。最後まで続くロスだけが本当のロス |
TCP RTT(ss -tiのrtt) | カーネルが接続ごとに測った往復時間 | 実際のゲーム接続の値なので、最も信頼できる。サーバー側でユーザーごとに確認できる |
| ゲーム内のPing | ゲームが独自のメッセージで測った往復時間 | ゲームループの中で測ると、フレーム・ティックの待ちが混ざる。回線が正常でも、サーバー・PCが忙しいと上がる |
ss -tiやeBPFツールを使って接続ごとのRTT・再送を集め、ASN別に確認します。pidstat -t)、ランキュー遅延、起動オプションだけで有効にできるGCログ。mtr。よく出くわす2つの状況での確認手順と、開発元・運営会社が自ら公開した実際の障害事例を集めました。各ステップと事例から、関連する原因カードにたどれます。
特定のアップデート・デプロイの後からラグ報告が増えたとき。「今回のアップデートからおかしい」という報告が集まったときや、グラフがある時刻から階段状に上がって高止まりしている場合に使う。
サービス提供国を新たに開くとき、または新しいリージョン・データセンターを追加するとき。オープン前の点検と、「国内は問題ないのに新しい国のユーザーだけラグい」という報告の切り分けの両方に使う。
ゲーム会社とインフラ企業が自ら公開したポストモーテム(事後分析)だけを選びました。要約は原文が明らかにしている範囲内で書いています。詳しい経緯は原文を参照してください。
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の対象探索コストが改修ポイントになる。ゲーム内の時間を遅くする設計で過負荷そのものはなくせないが、全員が同じ速さで遅くなるので、一部の行動だけが際限なく後回しになることを防げる。 原文
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接続、サーバーの設置場所の選定で解決する。通信事業者側の経路ポリシーは、外部(通信事業者)と協議する事項だ。サーバーをユーザー分布の中心近くに移すだけでも効果が大きいことも、この事例は示している。 原文
2020年2月末、League of LegendsのEUW・EUNE・BRサーバーで障害が何度も発生し、新たに始まるゲームの数が大きく減った。マッチング・ゲームサーバーなどのバックエンドサービスはどれも正常な状態だったが、流入するトラフィックがほとんどなかった。Riotは、不安定になりうるクラスターでトーナメントモード(Clash)を開催しないよう、日程を1週間延期した。ポストモーテムには、障害ごとの継続時間は書かれていない。 3つの要素が重なった。あるサービスへのリクエストが誤った形で組み立てられており、特定の条件で失敗と再試行を繰り返したため、リクエストが急増した。コンテナシステムとOSバージョンの既知の相性問題でOS内部のメモリがリークしていたが、アップグレードはRiotのコンテナ環境全体の約60%でしか終わっておらず、欧州・ラテンアメリカのクラスターは作業中だった。インターネットからのトラフィックを受けてフィルタリングし、バックエンドへ渡すエッジコンテナは、同じシャード(サーバー群)の中では別々のホストに配置されていたが、異なるシャード同士が同じホストに載るのは防げていなかった。そのため障害のたびに、少なくとも3つのシャードのエッジコンテナが1台のホストに集中していた。再試行の急増がそのホストに重なり、メモリリークがそのホストを停止させた。
バックエンドのサービスがどれも「正常だがトラフィックが来ない」という状態なら、その手前(エッジ・ゲートウェイ・ロードバランサー)を確認する。確認すべきシグナルは、ホスト別のインバウンド接続数の偏りと、特定リクエストの失敗・再試行の比率だ。主担当はゲーム開発チーム(サーバー:誤ったリクエストと再試行の方式)で、コンテナの配置ルール・OSのアップグレード・偏りのアラートはインフラチーム(サーバー機器・OS)が受け持つ。Riotはリクエストのコードを修正して再試行が急増しないように変え、シャード間の分散配置を実装するまでの間、偏りを検知するアラートを設けた。 原文
2021年1月22日、League of LegendsのEUWサーバーが5時間強にわたって正常に動作しなかった。ログイン中のユーザー数とゲーム中のユーザー数のメトリクスが一斉に途切れ、2回の再起動の間は、ログインは増えてもゲームはほとんど始まらなかった。 重要度の低い機能を担うDBのプライマリサーバーでハードウェア故障が起き、そのDBには予備サーバーへの自動フェイルオーバーが設定されていなかった。コネクションプールはDBごとに分かれていたが、すべてのプールが同じスレッドプールを使っており、故障したDBに送った処理が終わらないままスレッドを占有したため、システム全体で使えるスレッドが枯渇した。大量のアラートが鳴る中、最近受けた悪意あるネットワーク攻撃や別リージョンでのハードウェア作業を先に疑ったため、故障したDBのアラートに気づいたのは約1時間後だった。すべてのシステムが1つのJVMで動く構成だったため、再起動後の再接続の負荷の中でGCがプロセスを数秒ずつ止めると、メトリクス収集にも大きな空白が生じた。ログイン待機列も設定した上限を守らず、流入が安定しなかった。
重要ではないと考えていた補助的なDB一つでも、スレッドプールのような共有リソースを通じて全体を止めうる。確認すべきシグナルは、DB別の待機中リクエスト数とスレッドプール使用率、そしてログイン数に対してゲーム開始数が少なすぎる比率だ。担当はゲーム開発チーム(サーバー:スレッドプールの分離・タイムアウト)とインフラチーム(DB:自動フェイルオーバー)だ。アラートが大量に出ているときは最近経験した問題(攻撃など)から疑いがちなので、切り分けの順序(範囲 → 時点 → 階層)に沿って一つずつ除外する。再起動後は、ログイン待機列が設定どおりに流入を制限しているかもあわせて確認する。 原文
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%ずつ増やした。 原文
2021年12月、拡張パッケージ『暁月のフィナーレ』(Endwalker)のアーリーアクセス開始から、各ワールドが極度に混雑した。ログイン待機列が長くなり、キャラクター選択画面からログインするときや待機列で待っている間にエラー2002が頻発した。一部のワールド・ゾーンのダウン(エラー3001)や待機列のタイムアウト(エラー4004)も起きた。12月11日のお知らせの時点でも、アーリーアクセス8日目で混雑が続いていた。 エラー2002は2つのケースで発生する。1つは、論理データセンターごとの待機人数が17,000人を超えたときだ。待機列が長くなりすぎてログインサーバーがダウンするのを防ぐための上限で、このときはクライアントが完全に終了する。12月7日に開発用の予備機材をロビーサーバーに投入して上限を引き上げると、このエラーは減ったものの、待機列はかえって長くなった。もう1つは、待機中のユーザーの回線が不安定なときだ。待ち時間が長くなるにつれ、インターネット経路のパケットロスやWi-Fiの不安定さで接続が一瞬切れることが増えた。ロビーサーバーは数十秒から1分ほど再接続を待ち、その間に再接続できれば待機列の途中から再開できるが、それを過ぎると最後尾に並び直しになる。スクウェア・エニックスは、報告の大半がこのケースだとしている。半導体不足のため、ワールドをすぐに増やすこともできなかった。
待機列が長くなるほど、待機中のユーザー回線で起きる瞬断が接続エラーに変わる。同じ混雑の中でも、Wi-Fiや不安定な回線を使う人にエラーが集中する「一部のユーザーだけに起きる問題」になる。確認すべきシグナルは、待機列の長さ・待ち時間と、切断理由のうち待機中の切断が占める割合だ。主担当はゲーム開発チーム(サーバー:待機列の上限と再接続の猶予時間)で、ロビー・ワールドサーバーの増設はインフラチームが一緒に行う。再接続の猶予時間を十分に取れば、ユーザー回線の瞬断が待機順を失う事態に発展するのを減らせる。 原文
多くのゲームが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)を設けることにし、ある拠点がほかの拠点のトラフィックを引き寄せられないよう優先度を調整した。 原文
多くのゲームがアップデートファイル・ランチャー・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を複数使うか、オリジンサーバーから直接取得する迂回経路を用意しておく。 原文
ゲーム会社の自社ネットワークとDNSにもそのまま当てはまるインフラ障害だ。2021年10月4日、Facebook(現Meta)のサービスに世界中で接続できなくなった。データセンター間をつなぐバックボーンがすべて切れ、インターネット側からFacebookのDNSサーバーを見つけられなくなった。ポストモーテムには、障害の継続時間は書かれていない。 定期メンテナンス作業中、世界全体のバックボーン容量を確認するために実行したコマンドが意図に反してバックボーンのすべての接続を切断し、こうしたコマンドを止めるはずの監査ツールはバグのため止められなかった。小規模拠点のDNSサーバーは、データセンターと通信できないと自らを異常と判断してBGP広報を取り下げる仕組みだったため、DNSサーバーは動いているのにインターネットから到達できなくなった。通常のアクセス経路も帯域外(out-of-band)アクセスもすべて断たれ、内部ツールもDNSを失ったため、エンジニアをデータセンターへ直接派遣する必要があり、セキュリティ手順のためにさらに時間がかかった。復旧時は、データセンターごとに電力使用量が数十MWずつ落ちていたため、一気に戻すと電力設備からキャッシュまで危険にさらされうると判断し、負荷を段階的に上げた。
すべての地域・すべての通信事業者で同時に接続不可・無限ロードが起きたら、ゲームサーバーよりも先にDNSとBGP経路を確認する。外部からのDNS問い合わせと公開されているBGP経路情報を使えば、社外からでも確認できる。主担当はインフラチーム(ネットワーク)だ。障害時に使う帯域外アクセス経路や内部ツールが同じDNS・ネットワークに依存していないかを事前に点検し、復旧時は再接続が一気に集中しないよう負荷を段階的に上げる。 原文
多くのゲームがサーバー・ログイン・データをパブリッククラウドに置いているため、ゲームも巻き込まれるタイプのインフラ障害だ。2021年12月7日午前7時30分(太平洋標準時)、北バージニアリージョン(us-east-1)の内部ネットワークが輻輳した。7時33分からEC2 APIのエラーと遅延が増えて新しいインスタンスを起動しにくくなり(インスタンスの起動は午後2時40分に回復)、コンソールへのログイン失敗、Route 53の設定変更不可、CloudWatchメトリクスの遅延と一部欠損が続いた。ネットワーク機器は午後2時22分に完全に回復した。すでに稼働していたEC2インスタンスと既存のDNS応答は影響を受けなかった。 メインネットワーク上のあるサービスの容量を増やす自動処理が、内部ネットワークの多数のクライアントで予期しない動作を引き起こし、接続試行が急増した。内部ネットワークとメインネットワークをつなぐ機器があふれて通信が遅延し、その遅延がさらに接続試行と再試行を増やして輻輳が続いた。クライアントにはこうした輻輳時にリクエスト間隔を広げるバックオフの仕組みがあったが、潜在的な不具合のため正しく動作しなかった。内部の監視も同じネットワークに依存していたため、運用チームはリアルタイムのメトリクスなしにログを頼りに対応した。
再試行の間隔を広げられないと、短い輻輳が数時間の障害になる。ゲーム側から見ると、稼働中のゲームサーバーは正常でも、新しいサーバーの増設(オートスケーリング)、クラウドAPIを使うログイン・マッチング・決済、監視がまとめて止まることがある。確認すべきシグナルは、クラウド事業者のステータスページ、クラウドAPIのエラー率、インスタンスの起動失敗だ。主担当は外部(クラウド事業者)だ。ゲーム開発チームはすべての再試行にランダムな間隔の指数バックオフと回数制限を設け、インフラチームは増設できなくても持ちこたえられる余剰容量と、別リージョンという代替手段を用意する。 原文
ユーザーが端末やルーターに自分で設定して使うパブリック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運営者・通信事業者)だ。ゲーム開発チーム(クライアント)が名前解決の失敗をほかのエラーと区別して表示すれば、カスタマーサポートがその場で切り分けられる。 原文
多くのゲームがサーバー・ログイン・データをパブリッククラウドに置いているため、ゲームも巻き込まれるタイプのインフラ障害だ。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エラー率、インスタンスの起動失敗、ロードバランサーの正常なターゲット数だ。主担当は外部(クラウド事業者)で、インフラチームはヘルスチェックの失敗で一斉に外れるサーバー数を制限し、別リージョンという代替手段を用意する。 原文
ゲーム開発チームやインフラチームが原因を探すとき、最も時間がかかるのは「いつ、どこで、誰に」起きたかを突き止める作業です。下の項目を埋めてもらえれば、ログやグラフからその瞬間をすぐに見つけられます。
ゲーム開発チームやインフラチームと話すときによく出てくる言葉です。検索欄に日本語か英語で入力してみてください。
白書の数値・デフォルト値・動作説明の根拠です。標準文書(RFC)、カーネル・OSのドキュメント、クラウド・エンジン・DBの公式ドキュメント、講演・論文など、信頼できる資料だけを集めました。原因カードや各章末の「出典」からも同じ資料にたどれます。バージョンが変わるとデフォルト値も変わることがあるので、実際に適用する前に、使っているバージョンのドキュメントを確認してください。
資料616件、発行元83組織。一覧はテキスト版の参考文献にあります。