負荷テストスクリプトについて。

どの様な負荷をかける事によって得られた結果なのかについて、それなりに書いておきます。
負荷テストは、負荷のかけ方によって、180度違った結果が出る事があります。


今回は、Seasar2とSpring2の比較をしていますが、
僕がSeasar2寄りなモノの考え方をしているのは事実であり、その一点のみにおいて、Spring側は不利です。
例えば、Seasar2では、HotDeployと言う、パフォーマンスを犠牲にして開発効率を優先する機能がありますが、
当然の事ながら、この負荷テストを行うにあたって、当該機能はOFFになっています。
又、非常に単純な方法で負荷をかけていますので、現実の案件でやるべき負荷テストとは、
テストとしての品質において非常に劣っていると言わざるをえません。*1


基本的には、これから負荷テスト的な事をやりたいと思っている人の参考に少しでもなれればイイなぁ…と、思います。

#!/bin/bash
rm -f seasar2_struts.log
URL=http://localhost/employee-seasar2-struts/empList.do
wget $URL
rm empList.do

for n in 0 1 2 3 4
do
ab -n 20000 -c 50 -t 5000 $URL >>seasar2_struts.log
done

これは、Struts + S2.4 + Kuina-Dao + JPA(Hibernate)用のスクリプトですが、
他のスクリプトも、大体同様のスクリプトです。
wget で一度だけ最初に処理を動かすべくリクエストを送信している所がポイントです。
TeedaにせよJSPにせよ、最初のリクエストが来た時に初めて動作する初期化プロセスや、
そもそも、クラスのローディング処理はそれなりにある訳で、
最初の一回目の処理コストを平均の中に含めてしまうと、
出てくる数字が著しく歪む可能性が高い為、こういう風にしています。


使っているのは、「Apache HTTP server benchmarking tool」、スクリプトを見て分るとおり、
非常に単純なGETリクエストを、物凄い勢いで只投げているだけです。*2


リクエストの回数とスレッド数の設定には、特に根拠がある訳ではありませんので、
ここは、よく注意して下さい。
ECサイトの様に同時接続数の多いシステムから見ると、同時接続数50と言うのは、
まぁ、さもありなん…と考えているのですが、
逆に、ある時期だけ動作する社内向けの、必然性は高いが負荷は低いシステムから見ると、
同時接続数50は、かなり多いかもしれません。
また、単一のプロセスに対して、一気に負荷をかけている為、
クラスタ化した場合*3に、全く違う結果になる可能性があります。


特に、スレッド数は、フレームワーク内の同期化部分の多寡によって、
結果のスループットが大きく変わる部分ですので、注意が必要です。
例えば、コネクションプーリングを使用する場合には、
このスレッド数と、プーリングするコネクション数に差分が出ない様にする事で、スループットが、理論的に最大化します。


又、localhostに対してリクエストを送信していますので、
負荷を受ける側のサーバが本来なら使える筈の、CPU処理時間やメモリと言ったリソースの一部を、
ApacheBench自体が食い潰してしまっています。
Topコマンドで見ていると、大体、4〜7%程度のCPUを使っていました。

*1:ちゃんとした負荷テストはのち程…出来るかなぁ…

*2:このテストでは、HTMLのレンダリング結果をキャッシュしてしまえば、非常に好成績を出す事が出来ますが、そういう意図の負荷テストではありません。

*3:例え、それが同一筐体内でプロセスを複数にしただけであっても…