JMeterを使って分間N件の負荷を均等にかける

f:id:nami_ki:20220308123012p:plain

こんにちは!インフラ担当の木村奈美です。

今回は、JMeterを使って均等に負荷をかける方法をご紹介します。

はじめに

負荷試験の要件によっては、ゆるやかな負荷を均等にかけたい場合があります。 例えば、分間100件のリクエストを均等に実行し、これを10分間継続させるには、どうやって設定すれば良いでしょう?

f:id:nami_ki:20220307103945p:plain
分間のリクエストを均等にしたい

答え

結論から言うと、以下のように設定します。 なお、ここでは話を分かりやすくするために、サンプラー数は1つとしています。

  • スレッドグループ
    • スレッド数: 100
    • Ramp-Up期間: 1分(60秒)
      • すべてのスレッドが起動するまでの時間
      • この時間内で、 等間隔に スレッドが起動する
    • ループ回数: 10
  • 定数スループットタイマ
    • ターゲットスループット: 1.0
      • ループが一気に実行されてしまわないように、スレッド単位のスループットを設定する

実際の設定例は以下のスクリーンショットをご覧ください。

f:id:nami_ki:20220308113744p:plain
JMeter設定例

このように設定すると、以下の図のような挙動になります。白い四角はリクエストです。

f:id:nami_ki:20220308113839p:plain
この設定で実行した場合の挙動

要点

今回の目的を実現するにあたり、大きく2つの要点があります。 なお、スレッドやループの概念については他に優れた記事がいくつもあるため、説明を省略します。

要点その1: Ramp-Up期間を1分にする

Ramp-Up期間とは、すべてのスレッドが起動するまでの時間です。 この時間内で、等間隔にスレッドが起動します。 今回は1分間のリクエストを等間隔にしたいため、1分(60秒)を指定します。

スレッドが起動した後どのようにループさせるかは、後に説明する定数スループットタイマとループ回数で制御します。

要点その2: 定数スループットタイマを設置する

本件の要です。

定数スループットタイマは、スレッド単位のスループットを制御します。 スレッドグループ全体のスループットではないので注意です。 1

定数スループットタイマを使わない状態でループ回数を指定すると、スレッドが起動した瞬間に全てのループが実行され、一気にダダダッとリクエストが走ります。

f:id:nami_ki:20220307104703p:plain
定数スループットタイマなしのイメージ

定数スループットタイマを使うことで、スレッドごとのループの間隔を制御できます。 それらのスレッドをRamp-Up期間で等間隔に起動することで、結果的に等間隔なリクエストがループする状態を作り出すことができるのです。

f:id:nami_ki:20220308113930p:plain
定数スループットタイマありのイメージ

定数スループットタイマは、「追加 > タイマ」から追加できます。英語では「Constant Throughput Timer」です。 スレッドグループやコントローラに含めて利用します。

今回は、「Calculate Throughput based on」は「this thread only」としています。

もっと高負荷の場合は?

例えば6000件/分の負荷をかけたい場合、6000スレッドとするのでしょうか。 いいえ、そうはしません。

スレッドを多く起動しすぎると攻撃サーバーのメモリが不足し、スレッドが希望数起動しない、動作が重くなる等の可能性があります。そうなると十分な負荷がかけられません。 2

この場合、スレッドあたりのスループットを増やしてスレッド数を減らすのが適切と考えられます。

  • スレッド数: 300
  • Ramp-Up期間: 60
  • 定数スループットタイマ: 6000/300=20

適切なスレッド数がいくつになるかは、攻撃サーバーのスペックやリモートサーバー(Slave)の台数によります。スレッドを増やしすぎてうまく動かない場合は調整しましょう。

最後に

やり方が分からなくて調べていたとき、Googleで「JMeter リクエスト 均等」というサジェストが出るものの、検索しても答えがヒットしなかったので、ならば自分が答えを書こうと思ってこの記事を書きました。 どなたかのお役に立てれば幸いです。


  1. 定数スループットタイマの設定項目「Calculate Throughput based on」で「all active threads」を選べば、スレッドグループ全体のスループットが指定の値になるよう実行されます。ただし、「active threads」とはすでに起動しているスレッドであり、最初に全てのスレッドが起動するまでのRamp-Up期間においてはこの通りになりません。今回はRamp-Up期間も含めて等間隔にしたかったためこの設定は利用しませんでした。

  2. ここではメモリの負荷についてのみ言及していますが、高負荷になるとネットワークの負荷も問題になる可能性があります。ネットワークがボトルネックにならないように、JMeterのリモートサーバー(Slave)を複数台用意したり、ネットワーク的に近い場所に攻撃サーバーを置いたり(対象サーバーがAWSなら攻撃サーバーもAWSに置くなど)することを推奨します。