ちょっとした負荷テストを行なうのに、apache に付属の ab コマンド(Apache Bench)プログラムが便利に使うことが可能です。
先日ちょいと顧客さんの環境内において負荷試験をやる機会があり、一瞬はまった話を書いておこうと思います。
サーバが違う!?
まずは、どういう現象にはまったのかを書いておきましょう。
調査を行なったのは、ウェブサーバ(すでに実運用中)、データベースサーバの2台構成のシステムです。
このうち、ウェブサーバに関してはすでに様々なコンテンツが稼動中で、複数のコンテンツ提供のためにバーチャルホストが組んであります。
このバーチャルホストで切られたコンテンツのひとつについて、データベースアクセス処理を更新したことでパフォーマンスがどの程度あがったのかを検証すると言うのが今回のミッションです。
まずは、wget なるコマンドを使って、転送されてくる HTML ファイルの内容が正しいかを確認。これは、ブラウザを使った場合に送られる様々なヘッダが処理に影響がないかどうかを確認するためです。
この段階ではなんら問題はなし。
下手なヘッダを送らなくても、テスト用のコンテンツはきちんと動作していることが確認できました。
と言うわけで、早速、Apache Bench によるテストを実行。
あれ?
まったく動きません。
Complete requests: 100 Failed requests: 0 Write errors: 0 Non-2xx responses: 100
みたいな感じで、全てが、Non-2xx responses になってしまうのです。
再度、ab コマンドと同様、コマンドラインから起動される形式の User Agent から確認してみますが、やはり問題はありません。
タイプミスがないことを確認するために、スクリプトを作って、きっちり動く wget の側からコピー&ペーストしましたが現象は変わりません。
そこで、ウェブサーバ側のログを調べてびっくり。
wget からの要求はログに残っているにもかかわらず、ab からの要求はまったくログに残っていないのです。
この段階でようやく、原因がテストを行なっているコマンドではなくて、ネットワークなどの設定にあることがわかったわけでありました。
ネットワーク設定
先ほどからバーチャルホストを切ったウェブサーバと書いていましたが、どうやらこのあたりが原因だろうと言うことで調べ始めました。
wget は動くのに、ab は動かないわけですから、きちんと動く理由もどこかにありますし、一方で動かない理由もあるはず。
そこで、調べるのがこのコマンド。
$ host hoge.example.com
おぉー。なるほど、いきなりわかりました。
テストを行なおうとしているマシンは、社内のローカルアドレスを持っていますが、それをルータの機能をつかってポートフォワードして外部に公開しています。
そのため、ab コマンドは、その外部のアドレスを持つホスト(実際にはルータ)に対してアクセスに行ってたという話。
ほんでルータの側は、内部からのアクセス=ルータの設定変更画面要求として、パスワード認証を行なうための応答を返していたと言うのが、この現象だったわけです。
それなら、今度はなんで、wget で動いてたかと言う話になります。
それの理由は、/etc/hosts にありました。
社内から、バーチャルホストのテストを行なうために、社内から、サーバにアクセスする際には、この /etc/hosts ファイルを変更して対応していたと言う話。
なるほど、一件落着です。
対策
ここまで分かってしまえば話は簡単です。
ab コマンドでは、ホスト名でURLを指定せず、直接IPアドレスを使用すれば良いのです。ただし、サーバの側ではどのバーチャルホストにアクセスに来ているのかを判断できませんから、この判断材料となるヘッダを追加してあげればよいのです。
こんな感じ。
$ ab -H 'host: hoge.example.com' http://192.168.?.?/
というわけで、ようやくテストが出来るわい。
