1. 序章

仕事に適したツールを選択することは困難な場合があります。 このチュートリアルでは、3つのWebアプリケーション負荷テストツール(Apache JMeter、Gatling、The Grinder)を単純なREST APIと比較することで、これを単純化します。

2. 負荷テストツール

まず、それぞれの背景を簡単に確認しましょう。

2.1. ガトリング

Gatling は、Scalaでテストスクリプトを作成する負荷テストツールです。 Gatlingのレコーダーは、Gatlingの重要な機能であるScalaテストスクリプトを生成します。詳細については、 Intro toGatlingチュートリアルをご覧ください。

2.2. JMeter

JMeter は、Apacheによる負荷テストツールです。 これは、構成に使用できる優れたGUIを提供します。 ロジックコントローラーと呼ばれる独自の機能により、GUIでテストをセットアップするための優れた柔軟性が得られます。

スクリーンショットと詳細については、 Intro toJMeterチュートリアルをご覧ください。

2.3. グラインダー

そして、最後のツールである The Grinder は、他の2つよりもプログラミングベースのスクリプトエンジンを提供し、Jythonを使用します。 ただし、Grinder3にはスクリプトを記録する機能があります。

グラインダーは、コンソールとエージェントのプロセスを可能にするという点でも、他の2つのツールとは異なります。 この機能は、エージェントプロセスの機能を提供するため、負荷テストを複数のサーバーにまたがってスケールアップできます。  開発者がデッドロックとスローダウンを見つけるために構築された負荷テストツールとして特に宣伝されています。

3. テストケースの設定

次に、テストのためにAPIが必要です。 API機能には次のものが含まれます。

  • 報酬レコードの追加/更新
  • 1つまたはすべての報酬レコードを表示する
  • トランザクションを顧客の報酬レコードにリンクする
  • 顧客報酬レコードのトランザクションを表示する

私たちのシナリオ:

ある店舗では、貯蓄を得るために顧客リワードアカウントを必要とする新規およびリピーターの顧客を対象に全国販売を行っています。 報酬APIは、顧客ID によって顧客報酬アカウントをチェックします。報酬アカウントが存在しない場合は、アカウントを追加して、トランザクションにリンクします。

この後、トランザクションを照会します。

3.1. 私たちのRESTAPI

いくつかのメソッドスタブを表示して、APIの概要を簡単に見てみましょう。

@PostMapping(path="/rewards/add")
public @ResponseBody RewardsAccount addRewardsAcount(@RequestBody RewardsAccount body)

@GetMapping(path="/rewards/find/{customerId}")
public @ResponseBody Optional<RewardsAccount> findCustomer(@PathVariable Integer customerId)

@PostMapping(path="/transactions/add")
public @ResponseBody Transaction addTransaction(@RequestBody Transaction transaction)

@GetMapping(path="/transactions/findAll/{rewardId}")
public @ResponseBody Iterable<Transaction> findTransactions(@PathVariable Integer rewardId)

報酬IDによるトランザクションのクエリや、顧客IDによる報酬アカウントの取得などの関係に注意してください。 。 これらの関係により、テストシナリオを作成するためのロジックと応答の解析が強制されます。

テスト対象のアプリケーションは、永続性のためにH2インメモリデータベースも使用します。

幸いなことに、私たちのツールはすべてそれをかなりうまく処理し、他のものよりも優れているものもあります。

3.2. 私たちのテスト計画

次に、テストスクリプトが必要です。

公平に比較するために、各ツールに対して同じ自動化手順を実行します。

  1. ランダムな顧客アカウントIDを生成する
  2. 取引を投稿する
  3. ランダムな顧客IDとトランザクションIDの応答を解析します
  4. 顧客IDを使用して顧客報酬アカウントIDを照会する
  5. リワードアカウントIDの応答を解析します
  6. 特典アカウントIDが存在しない場合は、投稿を追加してください
  7. トランザクションIDを使用して、更新された報酬IDで同じ初期トランザクションを投稿します
  8. 報酬アカウントIDですべてのトランザクションを照会します

各ツールのステップ4を詳しく見てみましょう。 そして、完成した3つのスクリプトすべてのサンプルを必ずチェックしてください。

3.3. ガトリング

Gatlingの場合、Gatling APIは堅牢で多くの機能が含まれているため、Scalaに精通していると開発者にメリットがあります。

GatlingのAPIは、ステップ4でわかるように、ビルダーDSLアプローチを採用しています。

.exec(http("get_reward")
  .get("/rewards/find/${custId}")
  .check(jsonPath("$.id").saveAs("rwdId")))

特に注目すべきは、HTTP応答を読み取って検証する必要がある場合のGatlingのJSONパスのサポートです。 ここでは、報酬IDを取得して、ガトリングの内部状態に保存します。

また、Gatlingの式言語により、動的なリクエストの本文が簡単になります Strings:

.body(StringBody(
  """{ 
    "customerRewardsId":"${rwdId}",
    "customerId":"${custId}",
    "transactionDate":"${txtDate}" 
  }""")).asJson)

最後に、この比較のための構成。 シナリオ全体の繰り返しとして設定された1000回の実行、atOnceUsersメソッドはスレッド/ユーザーを設定します。

val scn = scenario("RewardsScenario")
  .repeat(1000) {
  ...
  }
  setUp(
    scn.inject(atOnceUsers(100))
  ).protocols(httpProtocol)

Scalaスクリプト全体はGithubリポジトリで表示できます。

3.4. JMeter

JMeterは、GUI構成後にXMLファイルを生成します。 このファイルには、プロパティとその値が設定されたJMeter固有のオブジェクトが含まれています。次に例を示します。

<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Add Transaction" enabled="true">
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="Transaction Id Extractor" enabled="true">

testname 属性を確認してください。上記の論理的な手順に一致すると認識されるため、ラベルを付けることができます。 子、変数、依存関係のステップを追加する機能により、スクリプトが提供する柔軟性がJMeterに与えられます。 さらに、変数のスコープも設定します。

JMeterの実行とユーザーの構成では、ThreadGroupsを使用します。

<stringProp name="ThreadGroup.num_threads">100</stringProp>

jmxファイル全体を参照として表示します。 可能ではありますが、XMLで .jmx ファイルとしてテストを記述しても、フル機能のGUIでは意味がありません。

3.5. グラインダー

ScalaとGUIの関数型プログラミングがなければ、TheGrinder用のJythonスクリプトはかなり基本的に見えます。 いくつかのシステムJavaクラスを追加すると、コード行が大幅に少なくなります。

customerId = str(random.nextInt());
result = request1.POST("http://localhost:8080/transactions/add",
  "{"'"customerRewardsId"'":null,"'"customerId"'":"+ customerId + ","'"transactionDate"'":null}")
txnId = parseJsonString(result.getText(), "id")

ただし、JSON文字列の解析など、より多くの文字列メンテナンスコードが必要になることで、テストセットアップコードの行数が少なくなります。 また、 HTTPRequestAPIは機能がスリムです。

Grinderを使用して、外部プロパティファイルでスレッド、プロセス、および実行値を定義します。

grinder.threads = 100
grinder.processes = 1
grinder.runs = 1000

The Grinderの完全なJythonスクリプトは、thisのようになります。

4. テストラン

4.1. テストの実行

3つのツールはすべて、大規模な負荷テストにコマンドラインを使用することを推奨しています。

テストを実行するには、Gatling オープンソースバージョン3.4.0をスタンドアロンツールとして使用し、 JMeter5.3およびTheGrinderバージョン3を使用します。

ガトリングに必要なのは、JAVA_HOMEGATLING_HOMEが設定されていることだけです。 ガトリングを実行するには、次を使用します。

./gatling.sh

GATLING_HOME/binディレクトリにあります。

JMeterには、構成のためにGUIを起動するときにプロンプトが表示されるように、テストのGUIを無効にするパラメーターが必要です。

./jmeter.sh -n -t TestPlan.jmx -l log.jtl

Gatlingと同様に、GrinderではJAVA_HOMEGRINDERPATHを設定する必要があります。 ただし、さらにいくつかのプロパティが必要です。

export CLASSPATH=/home/lore/Documents/grinder-3/lib/grinder.jar:$CLASSPATH
export GRINDERPROPERTIES=/home/lore/Documents/grinder-3/examples/grinder.properties

上記のように、スレッド、実行、プロセス、コンソールホストなどの追加構成用にgrinder.propertiesファイルを提供しています。

最後に、コンソールとエージェントを次のようにブートストラップします。

java -classpath $CLASSPATH net.grinder.Console
java -classpath $CLASSPATH net.grinder.Grinder $GRINDERPROPERTIES

4.2. 試験結果

各テストは、100ユーザー/スレッドで1000回実行されました。 ハイライトのいくつかを開梱しましょう:

成功したリクエスト エラー 合計テスト時間(秒) 平均応答時間(ミリ秒)  平均スループット
ガトリング 500000リクエスト 0 218秒 42 2283 req / s
JMeter 499997リクエスト 0 237秒 46 2101 req / s
グラインダー 499997リクエスト 0 221秒 43 2280 req / s

結果は、平均スループットに基づいて、3つのツールの速度が類似しており、Gatlingが他の2つのツールをわずかにエッジアウトしていることを示しています。 

各ツールは、より使いやすいユーザーインターフェイスで追加情報も提供します。

Gatlingは、実行の最後に、実行全体と各リクエストの複数のグラフと統計を含むHTMLレポートを生成します。テスト結果レポートのスニペットは次のとおりです。

JMeterを使用する場合、テスト実行後にGUIを開き、結果を保存したログファイルに基づいてHTMLレポートを生成できます。

JMeter HTMLレポートには、リクエストごとの統計の内訳も含まれています。

最後に、Grinder Consoleは各エージェントの統計を記録し、以下を実行します。

グラインダーは高速ですが、開発時間が長くなり、出力データの多様性が少なくなります。

5. 概要

次に、各負荷テストツールの全体像を見てみましょう。

ガトリング JMeter グラインダー
プロジェクトとコミュニティ 9 9 6
パフォーマンス 9 8 9
スクリプト可能性/API 7 9 8
UI 9 8 6
レポート 9 7 6
統合 7 9 7
概要 8.3 8.3 7

ガトリング:

  • Scalaスクリプトで美しいレポートを出力する堅実で洗練された負荷テストツール
  • 製品のオープンソースおよびエンタープライズサポートレベル

JMeter:

  • コーディングを必要としないテストスクリプト開発用の堅牢なAPI(GUI経由)
  • ApacheFoundationのサポートとMavenとの優れた統合

グラインダー:

  • Jythonを使用する開発者向けの高速パフォーマンス負荷テストツール
  • クロスサーバーのスケーラビリティは、大規模なテストにさらに大きな可能性をもたらします

簡単に言えば、速度とスケーラビリティが必要な場合は、TheGrinderを使用してください。

見栄えの良いインタラクティブなグラフが、変更を主張するためのパフォーマンスの向上を示すのに役立つ場合は、ガトリングを使用してください。

JMeterは、複雑なビジネスロジックまたは多くのメッセージタイプを持つ統合レイヤーのためのツールです。 Apache Software Foundationの一部として、JMeterは成熟した製品と大規模なコミュニティを提供します。

6. 結論

結論として、ツールは一部の領域で同等の機能を持ち、他の領域では輝いていることがわかります。 適切な仕事のための適切なツールは、ソフトウェア開発で機能する口語的な知恵です。

最後に、APIとスクリプトはGithubにあります。