Skip to content

Instantly share code, notes, and snippets.

@umegaya
Last active April 1, 2016 08:31
Show Gist options
  • Save umegaya/732785073c67ca03cba7a7a4ed5273f3 to your computer and use it in GitHub Desktop.
Save umegaya/732785073c67ca03cba7a7a4ed5273f3 to your computer and use it in GitHub Desktop.
一子相伝の負荷テスト覚書

テスト計画の策定

  • 負荷テスト = プロダクション運用時に想定される負荷と近い負荷をかけることで

    • 実運用時にもシステムが安定稼動するかを保証する
    • 高負荷時にしか発生しないバグや異常な挙動を検出する
  • プロダクション運用時に想定される負荷を見積もるには

    • アクセス規模の見積もり

      • 瞬間的なピークと通常想定されるピーク、それぞれの負荷を見積もる
      • ピーク時の負荷 = ユーザー数 x アクティブ率のプレイヤーが同時にゲームのメインセッションをプレイする想定
      • 瞬間的なピーク = 秒間で、どのリクエストがどのくらいくるかの想定
      • 大きい方を採用する
    • アクセス種類の見積もり

      • リクエストごとに負荷がかかるシステムの部分(アクセス種類)は異なることがある。
      • 例:お知らせの配信 = アプリケーションサーバー + キャッシュ, ガチャを引く = アプリケーションサーバー + DB など。
      • できるだけすべてのアクセス種類をサーバーに処理させるほうが良い
      • アクセス種類が異なるリクエストの数は別々に見積もる
      • アクセス種類が同じリクエストの中で、頻度が支配的なものを把握しておく。 => テストの実装を楽するため
    • 規模 x 種別で、実際にサーバーにかけるべき負荷( = 秒間に送信するべきリクエストの種類と量)がもとまる

テストの実装

  • 上記で見積もられた負荷をかけるためのプログラムを用意する

  • ロボット vs ベンチマークツール

    • ロボット

      • 実際のゲームクライアントの実行中の通信と似た形でサーバーと通信を行うプログラム
      • プレイヤーが実際にゲームで行う頻度の高い操作をもとに、想定されている負荷をかけられるように、ループ可能な通信内容を決める
        • 例: お知らせを見る => ガチャを引く => デッキを編集する => クエストリストを取得 => クエスト開始 => 1~3分スリープ => クエスト終了 => お知らせを見る... など。
        • 同じアクセス種類のリクエストを両方送らなくても良い。1つのリクエストの頻度を調節することでほぼ同じ効果が得られる(楽をする)
        • 1ロボットプロセスで上記のようなセッションを複数作成(500~1000ぐらい?)することが多い
      • 実際に1セッション=1クライアントとみなすことができ、実際の運用時と近い負荷を与えられる
      • 通信のやり方が複雑な場合に有用(ゲームで他のクライアントの情報を一旦取得して使う必要があるなど)
      • テーラーメードになる部分が多いため、高コスト
    • ベンチマークツール

      • nginxならwrkなど、指定したURLへのアクセスを連続して行うようなプログラムを(必要なら複数パターン)動かし、サーバーシステムに負荷をかける
      • 通信のやり方が単純な場合に有用(基本的なMBaaSなど)
      • 既存のツールをそのまま使えるため、低コスト
  • ロボットの場合についてもう少し説明

    • 負荷テストは一度で終わるわけではないことに注意

      • 大きな改修をリリースあるいは開発する際、問題がないことをテストするために行っていったほうがいい
      • メンテナンス性が高いほうが良い
    • ロボットの開発手法

      • 完全に別のプロジェクトとして作成する
        • 導入コスト=低, メンテナンスコスト=高
      • 通信プロトコル部分などだけprotocol bufferやRAMLなどを使って共有できるようにしておく
        • 導入コスト=中, メンテナンスコスト=中
      • ゲームと完全にソースを共有して、ビルドオプションなどを変更してロボットが作れるようにしておく
        • 導入コスト=高, メンテナンスコスト=低
  • ゲーム本体を開発したスタッフが作成するのが最も効率が良い

    • 特にゲームの通信はクライアントに置かれた情報などを利用して通信することが多く、それらは正確にはドキュメントされていないことが非常に多い
    • 通信のタイミングなども重要だったりするが、同様にドキュメント化はされていないことが多い
    • これらを外部の人間が作れるように正確にドキュメント化し、それを維持していくと、概ね破綻するので開発スタッフが作成したほうが良い
    • ロボットの通信内容なども開発スタッフでないと実際のプレイ状況に使い設定が行えない
    • テストの実行で詳しく触れるが、必要に応じて柔軟にテストが行えること、テストの結果から問題点を正確に洗い出せることなどの面からも開発スタッフによってテストは実行されるべき

テストの実行

  • ロボット

  • サーバーシステムは可能であればプロダクション環境と同一のものを利用すべき

    • 難しい場合はアプリケーションサーバー1台あたりの目標を別途計算して、アプリケーションサーバー1台構成の別クラスタを作り、その分の負荷をかける
    • db/cacheも同様に減らすが、1台以下にできないので、十分な負荷をかけられない可能性がある
    • アプリケーションサーバーの台数を調節するか、db/cacheへのクエリ数などを別途見積もってそれだけでテストをするなど考える必要がある
    • RDS Auroraなら気にしなくてもいいかも
  • テストの実行中、おかしな点がないか確認する

    • 内部の実装や仕様を知る人でないと気づくことは難しいが、そういう人がやれば結構見つかることが多い
    • 実際のゲームプレイ. 表示や動作がおかしかったり、重すぎたりしないか
    • サーバー内部. 高負荷時にどういったリソースが多めに利用されているか、枯渇しそうなリソースはないか
  • テストの実行後、おかしな点がないか確認する

    • 内部の実装や仕様を知る人でないと気づくことは難しいが、そういう人がやれば結構見つかることが多い
    • 実際のゲームプレイ. 表示や動作がおかしかったり、重すぎたりしないか
    • サーバー内部. メモリやファイルハンドルがリークしていないか
  • 短時間での負荷テストが安定してきた場合、数時間以上負荷をかけ続けて見つかりにくいリソースのリークがないか確認する

結果の評価

  • 目標とするリクエスト数を送りきれているか

  • 負荷テスト中、テスト後にシステムは正常に動作しており、リソースのリークやパフォーマンスの大幅な劣化は発生していないか

  • 負荷テスト中、テスト後にゲームをプレイした場合に目に見える異常はないか

  • (現在のリソースの残り方から考えて)大ヒットして想定アクセスの~10倍くらいのユーザーが来た場合に対応可能そうか

    • ~100倍になったときのことを考える必要はないってgoogleの人が言ってました
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment