AWSのLightsailのWordPress(BitNami)へ移行する際の要点まとめ
BitNami(AW…
仕事で負荷テスト担当になり、負荷テストツールは何使おうかなーとかツールの選定から入れたので、たまたま見つけたGoで実装されたVegetaがとても良かったので紹介。
当初、王道のJMeterや、Erlangで実装されたTsungを考えたが、テストシナリオに複雑な要件がなかったのと、セットアップがめんどくさそうなのでパス。CLIで操作可能で、データの出力形式も選択肢が多いVegetaを選んだ。
Vegetaのインストールは、そのまま公式ドキュメントに書かれているコマンドを実行するとして(※Mac以外は基本的な環境としてGoの動作環境がないとダメ)、使い方についてもドキュメントの通り。コマンドラインツールなので、ドキュメントに書かれているオプションが全てとなっている(公式ドキュメントが丁寧に書かれているため、特に説明不要)。Vegetaの使い方の主なポイントは、vegetaコマンドへリクエストの内容を標準入力で与えることだ。また、攻撃の出力結果も同様で、実行結果が標準出力で出てくるので、これをコンソールに出力するのか、他にどうするか、などと言った具合だ。公式のExamlesに書かれているコマンドを説明すると、
<code></code> echo "GET http://localhost/" | vegeta attack -duration=5s | tee results.bin | vegeta report
「攻撃対象をhttp://localhost/とし、5秒間攻撃する。出力結果をresults.binに保存し、実行結果をコンソールに表示」
である。rateオプションが書いてないので、秒間リクエスト数がデフォルト値になる。恐ろしいことに、デフォルトが秒間50リクエストであった。リクエスト数の初期値から、まさにベジータ様の容赦のなさが伝わってくる値である。Vegetaの実行時にはrateオプションは必ず適切な値にすることを忘れないようにする。
公式ドキュメントのオプション説明がかなりよく書かれているので、基本的にやりたいことが分からない場合は公式に当たるのが良い。
自分の場合は、ShellScriptが扱えたので、ShellScriptでVegetaを操作した。何度もコマンドを叩くのが面倒だったので、テストシナリオを用意し、vegetaコマンドを内包しているスクリプトに渡せば自動的にシナリオ名のディレクトリを作成し、攻撃実行後はグラフデータのHTMLファイルと、サマリーをまとめたテキストファイルの2つを出力するようにした。
GitHubのリポジトリにこのスクリプトを置いたので、気になる方はご参考頂きたい。また、アクセスが面倒な方のために下記にもサンプルを掲載しておく(※基本的にはGitHubが最新であり、下記のサンプルについての今後の更新は確約しない)。下記の簡単な使い方は、テストシナリオ(と言っても、単一URLに対してのものなのだが)を書いたtxtファイルを用意し(シナリオの書式は公式ドキュメントを参照)、それをvegeta_attack.shに渡してあげるだけだ。スクリプトは改修の余地が多分にあると思うので、参考程度に…。
#!/bin/sh # Vegeta Parameters ##### DURATION=60 TIMEOUT=30 RATE=10 ######################### VEGETA=`which vegeta` OUTPUTDIR=attack_results DATE=`date +%Y%m%d%H%M%S` # Usage # chmod +x vegeta_attack.sh # echo test_shenario.txt | ./vegeta_attack.sh if [ -p /dev/stdin ] ; then TESTFILE=$(cat -) SCENARIO=$(echo ${TESTFILE} | sed "s/\.txt//" | sed "s/test_scenario\///") echo "シナリオ: ${SCENARIO} を実行" else echo "テストシナリオを入力してください" fi setup_directory() { if [ ! -e ${1}/bin ]; then mkdir -p ${1}/bin fi if [ ! -e ${1}/text ]; then mkdir -p ${1}/text fi if [ ! -e ${1}/html ]; then mkdir -p ${1}/html fi } setup_directory ${OUTPUTDIR}/${SCENARIO} FILENAME=${SCENARIO}_${DATE} echo "攻撃を実行中…" cat ${TESTFILE} | ${VEGETA} attack -duration=${DURATION}s -timeout=${TIMEOUT}s --rate ${RATE} -header ${HEADER} | tee ${OUTPUTDIR}/${SCENARIO}/bin/${FILENAME}.bin | ${VEGETA} report echo "攻撃を完了" echo "攻撃結果をテキストファイルに出力" cat ${OUTPUTDIR}/${SCENARIO}/bin/${FILENAME}.bin | vegeta report -reporter=text > ${OUTPUTDIR}/${SCENARIO}/text/${FILENAME}.txt echo "攻撃結果をHTMLに出力" cat ${OUTPUTDIR}/${SCENARIO}/bin/${FILENAME}.bin | vegeta report -reporter=plot > ${OUTPUTDIR}/${SCENARIO}/html/${FILENAME}.html
実際にVegetaでテストをしていると、データの複数形式での出力や整理が面倒だった。このスクリプトのキモとしては、1つのシナリオごとに1つディレクトリを作成し、その中にデータをまとめていくため、特に出力結果がごちゃごちゃと同階層に溜まっていくのを気にせずにテストに集中できることだろうか。普通と言ったら普通なのだが、バイナリファイルを後でポチポチvegeta reportコマンドを叩いてデータ出力をしていくのが、テストの件数が多い場合にはかなり面倒だったので、このようになった次第だ。
あとは、もしGoが書ければ、VegetaをGoのモジュールとしてロードし、より柔軟に負荷テストができそうだ。自分はGoが書けなかったので、ShellScriptを選択したが、VegrtaはGoが書ける人には特に相性の良いツールかもしれない。
攻撃クライアントがMacbookでもロードアベレージが急上昇することもなく(※攻撃対象ホストや、その他ネットワークなどの条件にもよるので、いかなる条件でも一概とは言えない)、エコに大量のリクエストを発生させることができ、Vegetaの使用感は非常に満足度が高かった。秒間1,000リクエストまではさすがに試しておらず、やったとしても200リクエストを5分間継続する程度だ。今回、Vegetaのコマンドベースである特性を利用し、テストシナリオと記事で紹介したような自作のスクリプトがあれば、オペレーションとして自分以外でも負荷テストの攻撃作業を問題なくできる状態にはできたと思う(テストは長いと眠くなったり、入力ミスなど、色々あるので個人的には作業手順を簡素化するのは重要だと思っている)。Vegeta自体がコマンドのため、それ単体では複雑なことは苦手なものの、その点については今回のように自前のShellScriptないし、プログラムでフォローすれば、本来Vegetaでこなせないこともできる。元は簡素だが、工夫次第で使いやすくVegetaは結構好きになる人も多いんじゃないかと思った。
Vegetaはコマンドラインベース、使用リソースがエコ、セットアップが容易、使い方も容易、といういうことで、取っ付きやすく、Vegetaは自分にはぴったりのツールであった。今後も、HTTP/HTTPSの負荷テストは、テスト条件を満たせそうなら、Vegetaを積極的に使っていくつもりだ。
プログラムを書きながらTranceを聴くのが良いですね。みなさんも聴いたほうがいいですよ、Trance。EDMよりハードトランスでしょ。
Discussion about this post