VMwareでmod_proxy_balancerによる負荷分散を試してみた

Apache2.2に搭載されているmod_proxy_balancer。このモジュールを使うと、Apacheの設定だけで簡単にロードバランサが導入できます。こういう負荷分散系のテストにはサーバが複数台必要になりますが、VMware Serverを使えばPC1台でもロードバランサの動作確認ができます。もちろんパフォーマンスのテストは難しいですが、個人で無料のソフトだけでこれだけのことができるなんて、いい時代になったもんです。

VMware Serverで鯖作り

まずはVMware Serverでサーバをいくつか用意します。今回は Fedora6CentOS5 で作ってみました。VMwareの設定はこのあたりを参考に。ローカルでテストするだけなので、ネットワークは全てNATで構成します。

ソフトは基本的にyumでお手軽インストールですが、phpyumで入れるとmb_ereg_matchがうまく動いてくれなかったので(日本語の判定に失敗する)、ソースからビルドしました。

また、各サーバ間をホスト名で参照できるように、/etc/hosts にホスト名を登録しておきます。

Apache + mod_proxy_balancer

次に、mod_proxy_balancerを使ってWebサーバを冗長化します。構成は最も簡単な、以下の形をとります。

     +-------+
     | proxy |
     +-------+
         |
   +-----+----+
   |          |
+------+   +------+
| web1 |   | web2 |
+------+   +------+

proxyをwww.dev.localとして、そこにwebn.dev.localがぶら下がります。

proxyサーバhttpd.confにこんな感じで設定を追加します。

#
# mod_proxy_balancer
#
ProxyRequests Off
ProxyPass /css !
ProxyPass /images !
ProxyPass / balancer://cluster/ timeout=2

<Proxy balancer://cluster/>
        BalancerMember http://web1.dev.local/ loadfactor=10
        BalancerMember http://web2.dev.local/ loadfactor=10
</Proxy>

css/, images/ 以下のファイルはproxyサーバ自身が担当します。それ以外のリクエストはそれぞれのアプリケーションサーバに振ります。

web1, web2それぞれに内容の異なるindex.htmlを設置し、ブラウザからhttp://www.dev.local/を叩くと、適宜web1, web2にリクエストが割り振られていることが確認できます。これでとりあえず最低限の環境が整いました。

ここで、アプリ側のApacheアクセスログを見ると、アクセス元がproxyサーバのIPになっています。もちろん、proxyサーバのログには本来のリモートホストが記録されていますが、アプリケーション内でリモートホスト欲しい時にこれでは困ります。

そこで登場、mod_rpaf。

こいつを導入することで、アプリサーバのログにも元々のアクセス元のリモートホストが記録されます。インストールは、アーカイブのREADMEからコピペ。

apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

http.confの設定も基本コピペ。

# if DSO load module first:
LoadModule rpaf_module libexec/apache2/mod_rpaf-2.0.so

RPAFenable On
RPAFsethostname On
RPAFproxy_ips 192.168.126.10 10.0.0.1

最後のRPAFporxy_ipsで指定するIPをproxyサーバのIPにします。バランサの設定をせっかくホスト名にしたのに、ここだけIPです。 proxyのIPを変えることはあまりないかも知れませんが、ちょっと面白くないですね。そのままホスト名を書いてもダメだったので、ここは後日の課題ということで。
こうして、各アプリケーションサーバにmod_rpafを導入したところで一段落です。ETagによるキャッシュの制御なんかもしたいところだけど、ひとまずここまで。

mod_proxy_balancerの導入については、以下のページを参考にしました。