2021/06/16
負荷テストツールってたまにしか使いませんが、実はけっこうな数のツールが公開されているのはご存知でしょうか?
ほとんどのツールは知られることなく消えていく運命にあるわけですが、たくさんあるのには理由があります。
そのあたりを中心に、負荷テストに携わる人がいま知っておきたい、知っておいて損はないツールを紹介していきたいと思います。
対象は、ソースが公開されているのもので、一定数ユーザーが存在していて開発が継続されているものに限定しています。
ここからは開発会社である我々プロの視点から見る、負荷テストツールを7つご紹介します。
ツールによる実装言語の違いや特徴をまとめていますので、ぜひ参考にしてくださいね。
公式:https://httpd.apache.org/docs/current/programs/ab.html
リポジトリ: https://github.com/apache/httpd/tree/trunk/support
実装言語: C
特徴: コマンドラインツール。シングルスレッド。
開発動機:httpdの試験用。
コメント:
シンプルなコマンドラインツールです。単一エンドポイントの性能を測りたい場合はかなり手軽に使えます。ただし、1コアしか使えないので、大きな負荷を発生させようとするとCPUがボトルネックになりがちです。
それから-c (concurrency) オプションもシングルスレッド&ノンブロッキングIOによる実装なので、カジュアルな用途や生成する負荷のボリュームが少ないときはうまくはまりますが、ガチ目な試験で使うのはおすすめしません。
単独のリポジトリがあるわけではなくhttpdのリポジトリ内に含まれていて、ソースも1ファイル(ab.c)だけなのは今回初めて知りました。
公式: https://jmeter.apache.org/
リポジトリ: https://github.com/apache/jmeter
実装言語: Java
特徴: GUIあり。90年代から今でも使われているツール。プラグイン方式で拡張可能。
開発動機:ウェブアプリケーションの負荷テスト。
シナリオ作成用の画面
Apache Benchでは難しい凝った試験をやろうと思ったら第一の選択肢に上がると思います。歴史も長いので触ったことのある人も多いと思います。たくさんの情報がウェブ上にあることも利用する上でのメリットになると思います。セッション管理やレスポンスの再利用など、負荷テストで使いたいであろう機能は一通り揃っています。もし必要な機能がなかったとしても誰かがプラグインを作って公開していることが多く、守備範囲はかなり広いです。
ただし、負荷テスト初心者であればJMeterを使うのはおすすめできません。まずJavaの実行環境が必要になるので、セットアップでつまずく可能性があります。それからシナリオを作成する上でJMeterでしか見ない単語(スレッドグループ、Ramp-Up期間、リスナーなど)がハードルを上げてきます。それらを乗り越えて使い方を覚えたとしたら、次は意図したとおりに負荷がかからないという問題に遭遇するはずです。マシンスペックや設定の問題だったりはするのですが、JMeterを使いこなすにはバッドノウハウが必要になることが多いため、初めての人にはおすすめしません。
公式: https://gatling.io/
リポジトリ: https://github.com/gatling/gatling
実装言語: Scala
特徴: Scalaでシナリオ作成。HTMLでレポート吐き出し。CI/CD連携。クラウド版もあり。
開発動機: JMeterがいやだったから。特にXML(注: JMeterのシナリオはXMLとして作成されます。直接読み書きするのがしんどい長さ・複雑さです)でバージョン管理がしづらいこと。
HTMLで出力した結果
コメント:
Scalaでアクターモデルを採用した実装となっています。JMeterより性能が良いです。
ドキュメントにサンプルとして記載されているようなベタなシナリオであれば問題ないのですが、凝ったシナリオが必要な場合はScalaを多少学ぶ必要があります。そしてScalaは直感的とは言えないシンタックスがけっこうあるので、Scalaを使いたい人でなければ選ぶ必要はないと思います。複数サーバを使った試験もできるのですが、各サーバに同じシナリオを配布&実行しその結果を集約してからメトリクスを計算するという原始的な方法。(注:有料のクラウド版との違いを明確にするためにこうしている節があります。OSS版に対する変更要望もビジネス上の理由(=クラウド版でビジネスやってるから)で受け入れないケースを過去のイシューで見ました。この部分のバランスをとるのはSaaS事業者にとって難しい問題ですね…。)
公式: https://locust.io/
リポジトリ: https://github.com/locustio/locust
実装言語: Python
特徴: Pythonでシナリオを記述。実行&結果のリアルタイム確認ができるウェブサーバを同梱。
開発動機: JMeterとTsungに満足しなかったから。JMeterは、ひどいGUIとXMLベースのシナリオだから。ユーザ数=スレッド数で、スレッドがたくさん増えたときのスケーラビリティが確保されてないから。(注:現在は複数台サーバで動作させるソリューションがあり解決されています。)Tsungに関してはスレッドの問題はなかったけどXMLベースのシナリオだったから。
実行画面
コメント:
Pythonを書くことに抵抗ない人にとっては良い選択肢だと思います。また複数サーバで連携しての実行が良い感じにサポートされており、大きな負荷を生成するためのハードルはJMeter/Gatlingに比べて低いです。バージョンアップを重ねることで穴が無くなってきており、私が使う分には今のところ困ったことはありません。おすすめできます。
実装言語: Go
公式: https://k6.io/
リポジトリ: https://github.com/k6io/k6
特徴: JSでシナリオを記述。シナリオコンバーターあり。ツール連携(CI、IDE、監視ツール、など)。クラウド版あり。
開発動機: 今までのツールはQA部門のためで、開発者に優しいツールがなかったから。GatlingはScalaのクラスでシナリオを定義するがScala自体がわかりづらいのにDSLを入れているからさらにわかりづらい。それからJVMに依存しているのもJava開発者以外が使いづらい。Locustはすごくいいけどパフォーマンスが悪い。
コメント:
現時点ではこれが最強だと思います。ドキュメントも充実していますし、連携等も想像できるようなものはすべて揃っています。パフォーマンスも悪くないです。以前はLoadImpactというクラウドベースの製品だったのですが、数年前にOSS版をリリースするとともに、k6という名前でリニューアルしました。ユーザーも順調に増えており、運営会社もOSS版にかなりリソースを割いているため、継続的な発展も見込めます。JSが書けるのであれば、一番おすすめできます。
公式: http://tsung.erlang-projects.org/
リポジトリ: https://github.com/processone/tsung
実装言語: Erlang
特徴: いろんなプロトコルに対応(TCP, UDP, MySQL, HTTP, 他多数)。シナリオはXML
開発動機: XMPPの負荷テスト用に開発。
コメント:
LocustにディスられていたTsungです。もともとはXMPPの負荷テスト用に作られたらしく、現在はいろんなプロトコルに対応した汎用性の高いツールです。シナリオはXMLで定義する方式ですが、JMeterよりはフォーマットが洗練されています。TCP/UDPレイヤーならなんでもいけるため、ゲーム等の独自プロトコルの試験などにも使えます。半面、HTTPやWebSocketなどのウェブプロトコルに関しては他のツールの方が特化している分使いやすいです。歴史がある割にはユーザ数が伸びていないのはそうゆいうところかもしれません。
リポジトリ: https://github.com/tsenart/vegeta
実装言語: Go
特徴: コマンドとしてもGoライブラリとしても利用可。結果をファイルに保存でき、色んなフォーマットに変換可能。
実行結果のHTML出力
コメント:
名前とリポジトリに設置された画像が少し前に話題になっていましたね。Apache Benchをもっと便利にしたようなものです。シンプルなAPIの負荷テストであればありですが、セッション管理とかファイルアップロードとかユーザ変数などはサポートしていないので、ユーザの遷移をシナリオとするような負荷テストには向きません。
以上、7個のツールを紹介しました。ここで紹介しなかったツールも含め、開発動機としては、JMeterが使いづらくて開発を始めたというツールが非常に多かったです。使いづらさを解消するためのアプローチは様々ですが、基本はシナリオをプログラムとして扱う、シナリオのフォーマットをわかりやすくするの2つで、前者が現在の主流と言えます。後者はシナリオ作成をUI化しやすいというメリットがあるので優れたシナリオ作成UIが出てくれば十分に巻き返す可能性もあります。
Hedgehogも含めて、サービスではUIでのシナリオ作成に挑戦しているものも多いので、それはまたの機会に紹介したいと思います。