負荷試験シリーズの実質初弾としては、ツールの選択について考えていきます。
基本的な基準を捉えつつ、私自身の要望を整理し、何に決定していったのか、という流れで参ります。
選定基準
前記事にも記載しましたが、このページは非常に参考になるので、まずは雰囲気だけでもサラリと読んでみるとよいです。- Open source load testing tool review 2020
 - Open Source Load Testing Tools: Which One Should You Use? | BlazeMeter
 
ツールは必要?
そもそも負荷試験ツールを使う必要があるのか、についてからですが、「必要はあります」で言い切って良いと思います。選択しない場合、自身で何かしらコーディングすることになるわけですが、実装内容によってはできなくもない話とはいえ、より複雑になるほどオレオレ度合いが高まってコスパの悪い技術的負債になる可能性大です。
10年以上前ならまだしも、今は優良なツールが揃っているので、まずはどのような機能や選択肢があるのかを学び、自身が何を求めているのかを整理し、それに合わせてツールを選択することが疑いようもなく最もコスパがよいでしょう。
なにを基準に選ぶ?
上記ページの表にもよくまとまっていますが、私なりに比較すべき項目をまとめるとこんな感じになります。クライアント
- 任意の処理をコーディングできるか
 - なんの言語か
 - なにをどのくらい変更する余地があるか
 - シナリオをどう表現するか
 - なにかのプログラミング言語でコーディング
 - マークアップ言語や独自設定で書く
 - シナリオ機能がそもそもない
 
サーバー
- マルチスレッドでの実行
 - できればサーバーのCPUを簡単にフル活用できる
 - できなければサーバーで負荷分散するか、プロセス単位で並列実行になる
 - どれでけ性能が良くとも、1vCPUのみで足りるとは思わないほうがよい
 - 複数サーバーリソースでの負荷分散実行
 - できない場合、1台での最大パワーに頼ることになるので、必須に近い
 - どのような構成か
 - 取り扱いやすさ
 - CPUパフォーマンス
 - サーバー性能あたり、どのくらいのRPS(requests per second)を発生させられるか
 - 負荷分散できない場合、1台が性能上限になるので重要になる
 - 負荷分散できるなら、クラウドではたいした問題にならない
 
運用・開発
- 試験実行の扱いやすさ
 - 複数ユーザーセッションによる同時接続の発生
 - リクエスト間隔による負荷調整
 - スレッド数・サーバー数の調整
 - 実行ログの確認
 - 試験結果の確認
 - 開発が盛んか
 - ドキュメントの品質
 - 一定以上の更新頻度に、新機能や改善、ユーザーの情報量を期待できる
 - 最低でも、すぐには死に体になることはない程度の雰囲気
 
さほど重要ではない項目
CPUパフォーマンス
上記のCPUパフォーマンスのところで、負荷分散できるなら問題ではない、と書きました。その理由は、クラウドではツールを動かすサーバーリソースを容易に・一時的に・大量に用意できるからです。もちろん、軽いに越したことはないですが、仮に軽量なソレと比べて2倍3倍重くても、2倍3倍のサーバー数で動かせば同等のRPSを発生することができます。それが20倍30倍と言われたらムムッと考えるかもですが、基本的には機能や扱いやすさを重視した方が幸せになれるはずです。
そのためにも、試験の準備と片づけが一手間でできるように仕込むことが大切です。数十分~数時間の試験ならば起動コストは誤差と言えるかもですが、数日に渡ってダラダラと起動する運用だと、台数用意すればいいじゃんっていう考え方がただの汚いマネーパワーになるからです。
ツール自体の言語
ツールそのものが何の言語で書かれているかは重要ではありません。なぜなら、試験サーバーの構築は自動化、もしくは既に存在するイメージを使うべきだからで、何度も構築したり、その言語自体でコーディングすることはないからです。スクリプトを書けるツールの場合、それらが同じ言語ならシンプルでヨシ!ですし、異なるならスクリプトの方の言語だけ気にすればいいということです。
運用基準
負荷試験を重要事項と認識し、成長する組織であるとするならば、その後も長くに渡って様々なサービスやチームにて負荷試験が何度も行われることになります。組織が小さめで余裕がない頃だと、場当たり的に得意そうな担当者が、自分の好きなように決めて試験するかもしれませんが、長い目でみるとそのシステムの価値が少なめになりがちです。
そのため、組織全体としてどのような運用になり、どのような仕組みになれば、より効率的で汎用的になるのか。といったことを考えて選定していくとよいです。例えば、試験の工程をこう考えて、総合的な最良を判断していきます。
- ツール用のサーバーリソース管理をするのは誰か
 - シナリオを考えるのは誰か
 - シナリオをコーディングするのは誰か
 - ツールの実行をするのは誰か
 - 試験結果を確認するのは誰か
 
負荷試験って作業はそうポコポコ頻度高くあるわけじゃないので、専任がいるというよりは、得意な人が担当するとか、アプリケーションの理解が深いサーバーサイドエンジニアがやるとか、になることが多いと思います。
そして、開発スケジュール的に、時間をかけるべきなんだけど時間をかけたくないタイミングでもあり、担当者が最も好むなり慣れた手法で取り掛かってなんとかやりきる、ってことも多いはずです。
それを許容というか放っておくとどうなるかというと、あちこちで慣れたツール、得意な言語、シナリオ資産、がバラバラに育っていきます。
それはあまり生産的な現象ではないので、チームや部署間で情報共有したり、もしくはSREといった1つのチームで全体を考慮した手法を確立する、のように意識的に正すことで、運用コストの無駄な肥大化を防ぐべきです。
Taurusという選択
できれば手法は組織で一本化した方がよいものの、もしかしたらバラバラの方が良かったり、既にバラバラだったりするかもしれません。そういう場合、まずは Taurus や AWSでの分散負荷テスト を検討するとよいでしょう。様々な負荷試験ツールを扱えるフレームワークといったところ。
私は少々触った程度ですし、進化もしているでしょうが、注意しておきたいのは取りまとめ的なツールであるがゆえに、各ツールの全機能を完全に扱えない場合があるということです。例えば、ツールによっては負荷分散に対応していないこともあります。
また、もし結局1つのツールしか使わない場合、Taurusを通さずそのツールをきっちり深堀りして仕上げたほうが、長期的には良い成果になる可能性も高いです。
複数の手法を必要とする組織で、あまり複雑・独自の仕組みを必要としない場合、もしかしたらピタリハマるかもしれません。とはいえ、結局は各ツールを動かすことに変わりはないので、ツールを単体で使った感触と、Taurusを通して使った感触、どちらも試すほうがよさげです。
ツール vs シナリオ
ここからは、私独自の考えを多く含んでいきます。負荷試験において最も重要なのはなにか。ツールが機能要件を満たしていて、使いやすいことか。それともツールのプログラミング言語が得意な人材が多いことか。シナリオを書きやすいことか。
色々ありますが、何が重要であったとしても、どの部位もツールや記法に慣れる必要がある、ということに変わりません。しかし強いて言うなら、ツールよりもシナリオの方が重要であると考えます。
なぜなら、ツールは自動化したり慣れればそれで済みますが、シナリオは言語や記法が異なったり、アプリケーションごとに作成しなくてはならないからです。多くの試験者が、多くの時間を費やす箇所で、なんならできればやりたくない作業、それがシナリオ作りでしょう。
ツールが最低限機能を満たして十分な負荷を出せることは必須ですが、もしその上で複数の選択肢があるとしたら、よりシナリオ作りが簡単でストレスの少ない方を選ぶことで、試験者の負担を減らすべきです。
選択しないという選択
こういった考察をぐるぐる考えて行き着いた先に、1つの強い願望が生まれました。それは『シナリオを書かない』という機能?です。試験者によって、得意なツールや言語が異なるだの、シナリオを考えたりコーディングするだの、そんなの関係ねぇ!システムにしてみようと思いつきました。また、他にも試験環境の準備なども可能な限り自動化し、試験結果もすぐ共有される──と欲望をモンモン膨らませた3つの機能概要がこれです。
- アプリケーションへのアクセスから自動的にシナリオを作成する
 - 複数台による試験を手軽にできる
 - 結果を簡単に共有・確認できる
 
細かくはもっと色々肉付けしていくことになりましたが、基本はこれを実現できる負荷試験ツールを選定し、独自にラッピングすることで、ツール・言語・シナリオ作成という標準的な選択を試験者から剥ぐ、という方向性で着手することにしました。
Locustを選択
私の欲望を叶えてくれるベースとなるツールは、わりとすぐに選定できました。Locust です。選択理由を同じ形でまとめると──クライアント
- 任意の処理をコーディングできるか
 - Python大好き → ラッパーを作る私の都合のみで良い。一応、業界事情的にも十分
 - ユーザーセッションもリクエストも、だいたいなんでもできる
 - シナリオをどう表現するか
 - 標準方法のtaskコーディングをせずに、別途アクセスデータでシナリオとして実行できた
 
サーバー
- マルチスレッドでの実行
 - できないので、自動化でvCPU数に合わせて複数プロセスを起動すれば問題ない
 - 複数サーバーリソースでの負荷分散実行
 - よくある master/worker 構成で扱いやすい
 - クラスタを自動化により一手間で組むことも可能
 - ユーザーIDなどworker毎に割り当てる仕組みはコーディングでなんとでもなる
 - CPUパフォーマンス
 - 機能がそれなりにあるので、軽量ではないが重くもなく普通
 - Pythonで動かしてりゃこんなもんだろうという印象
 - ECS Fargate 1vCPU あたり 750 RPS 出たので十分
 
運用・開発
- 試験実行の扱いやすさ
 - 期待した、ツールでの各種数値の調整はほぼ全て存在した
 - 細かい調整はコーディングでなんとでもなる
 - 実行ログの内容は十分
 - 試験結果をCSVやHTMLで取得できるので、そのまま活用できる
 - 開発が盛んか
 - ドキュメントは十分な情報がある
 - 掲示板やブログでのユーザー情報も十分ある
 - 開発頻度はそれなりにあるし、愛好家も目につくので息は長そう
 
ある程度の検証を進めて、ほぼ要件を実現できる確信をしたところで、ひたすらコーディングと実験をしていきました。最終的には、アクセスデータの自動生成と、設定ファイル編集&試験実行 にまで落とし込めたので、自分の中では楽しく大成功した感じ。
私の例は特殊な使い方ですが、標準的な使い方でもPython好きなら扱いやすくオススメですし、なにより大体なんでも実装できるってのが最高のポイントだと思います。
楽は大事
完成して、実際に数万ユーザーと数千RPSを何度も発生させて思ったのは、環境準備の手間が簡潔であることは必須だということです。ピッとクラスタ用意してピッと実行してピッと片付けできると使ってて心地よく、スポットで小一時間なら実質タダみたいなモンでしょって気持ちでやれるので、精神的な障壁が低いのは大切だなとつくづく感じました。「30分後に負荷かけてほしい」って言われても、「はいよ」で済む運用の強さよ。
どんなツールを選択するにしても、各作業における手作業コストを意識して、いかに効率的な試験にできるかってのを重視して設計するべきです。そして、それを求めればおそらく、独自の設計やコーディングが少なからず必要で、最初のそこを惜しまず時間をとって取り組めると、より早く正着に近づけるのではないでしょうか。
どのようなツール選定や設計になるかは、ホントそれぞれでしょうが、その取っ掛かりにでもなってくれれば、って感じです──が、
結局、長文になってしまったので、次回こそは小さめのテーマで短くまとめたい。きっと、そうする:-)
								