NBomberによる高負荷テストの実装:オープンループとクローズドループの使い分け

NBomberは、負荷テストシナリオを構築するために「オープンループ(到着レート制御)」と「クローズドループ(同時実行ユーザー制御)」という2つの異なる負荷シミュレーションモデルを提供しています。以下に、各モデルの特徴と具体的な実装例を解説します。

負荷モデルの比較

これら2つのモデルの核心的な違いを理解するために、主な特性と適用シーンを比較表にまとめました。

特性 オープンループモデル クローズドループモデル
制御対象 単位時間あたりのリクエスト到着レート システム上で稼働する仮想ユーザー数
挙動の特徴 システムの状態にかかわらず、常に新しいリクエストを生成し続ける システムの処理能力が限界に達すると、ユーザーはキューで待機状態になる
ユーザーライフサイクル 短命(リクエスト単位で生成・破棄) 長寿命(設定された期間中、何度もループ処理を行う)
最適な用途 検索エンジン、ニュースサイト、CDNエッジなど(ステートレスで独立したリクエスト) ECサイト、銀行システム、SaaSなど(ログイン~操作~決済といった一連のトランザクションが必要なケース)
推奨事項 迷った場合は、現実的なユーザー挙動に近いクローズドループから始めるのが安全です

具体的なシミュレーション手法とコード

選択したモデルに応じて、NBomberでは異なるシミュレーションメソッドを利用します。以下に主要な手法とC#による実装例を示します。

オープンループモデル(レート制御)

このモデルは、設定された間隔でリクエストを注入します。各仮想ユーザーは単一のタスクを実行した後、終了します。

1. 一定レートでの注入(Inject)

指定された期間中、一定の割合でリクエストを一定に生成し続けます。

var duration = TimeSpan.FromMinutes(1);
var targetRate = 100;

Simulation.Inject(
    rate: targetRate, 
    interval: TimeSpan.FromSeconds(1), 
    during: duration
);

2. 段階的レート変更(RampingInject)

リクエストの生成レートを、特定の時間をかけて開始値から終了値まで滑らかに増減させます。

// 最初の30秒でレートを0から100へ上昇
Simulation.RampingInject(rate: 100, during: TimeSpan.FromSeconds(30)),

// 次の30秒でレートを100から50へ低下
Simulation.RampingInject(rate: 50, during: TimeSpan.FromSeconds(30))

クローズドループモデル(同時実行制御)

このモデルは、テスト期間中存続する「長時間実行」の仮想ユーザーを作成し、継続的にシナリオをループ実行させます。

1. 一定ユーザー数の維持(KeepConstant)

テスト期間中、指定された数の同時実行ユーザーを維持し続けます。

var concurrentUsers = 20;
var testDuration = TimeSpan.FromSeconds(30);

Simulation.KeepConstant(
    copies: concurrentUsers, 
    during: testDuration
);

2. 段階的ユーザー数変更(RampingConstant)

同時実行ユーザー数を、指定時間内で滑らかに増減させます。典型的な「ウォームアップ(Ramp Up)」→「安定(Keep)」→「クールダウン(Ramp Down)」のパターンを構築できます。

// 30秒かけてユーザー数を0から50に増加
Simulation.RampingConstant(copies: 50, during: TimeSpan.FromSeconds(30)),

// 50ユーザーで30秒間維持
Simulation.KeepConstant(copies: 50, during: TimeSpan.FromSeconds(30)),

// 30秒かけてユーザー数を50から0に減少
Simulation.RampingConstant(copies: 0, during: TimeSpan.FromSeconds(30))

3. 総反復回数の指定(IterationsForConstant)

特定数のユーザーを起動し、テスト全体で指定された総反復回数(イテレーション)に達するまで実行し続けます。

注意点:このモードは他のシミュレーションタイプと組み合わせて使用することはできません。

var userCount = 100;
var totalIterations = 1000;

Simulation.IterationsForConstant(
    copies: userCount, 
    iterations: totalIterations
);

導入と構成のアドバイス

  • モデルの選定: ユーザーの一連の操作フロー(ログイン→商品閲覧→購入)を模倣する必要があるWebアプリケーションやAPIの場合、クローズドループモデルが実際のユーザー挙動により近くなります。一方、メッセージキューへの投入や独立したAPI呼び出しのような、状態を持たないリクエストの流れをテストする場合はオープンループモデルが適しています。
  • シミュレーションの組み合わせ: `IterationsForConstant`を除くすべてのシミュレーションは、単一のテストシナリオ内で組み合わせて使用可能です。これにより、複雑な負荷曲線(例:Ramp Up → Plateau → Spike)を作成することができます。
  • 複合シナリオテスト: NBomberでは、1つのテスト実行内でオープンループとクローズドループの異なるシナリオを並列に実行することが可能です。これは、現実世界で混在する様々なトラフィックパターンを再現する際に非常に有効です。

タグ: NBomber C# LoadTesting DotNet PerformanceTesting

7月4日 23:42 投稿