RailsをApacheとMongrel_clusterで動かす(中級編その2)

mongrelを複数起動していても1つの画面にcss/javascript/images等静的なデータがある場合に、それら全てをmongrelに処理さすのは良い方法ではないと想う。

というのはmongrel_clusterで起動できるmongrelの数は有限だし1つのmongrelプロセスが同時に処理できるのは1リクエストに限られるので、複雑なファイルから構成される1画面を表示するとなるとたちまち多くのmongrelプロセスが占有されてしまう。

そこでApachemod_rewriteを利用して、「document_root配下に実在するファイルはmod_proxy処理を行わない」という設定に変更してみた。

まず、今利用しているApache2.2.11は以下の用なconfigureになっている。

# configure --enable-proxy --enable-proxy-balancer --enable-module=so --enable-rewrite

このため、このapacheではmod_rewriteが既に利用な環境としてインストールされている。そこで、httpd.confを以下の用に修正した。

#ModRewrite利用
RewriteEngine On
#DocumentRoot配下にリクエストファイルが存在するか?
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
#ファイルが存在するなら直接読み込み。
RewriteRule (.*) $1 [L]

#これはFowardリクエスト禁止の設定。今回の定義とは直接関係ないがセキュリティー強化上追加
ProxyRequests Off

ProxyPass /bbs/ balancer://mycluster/
ProxyPassReverse /bbs/ balancer://mycluster/
<Proxy balancer://mycluster/>
        BalancerMember http://192.168.0.138:8000/bbs loadfactor=20
        BalancerMember http://192.168.0.138:8001/bbs loadfactor=20
        BalancerMember http://192.168.0.138:8002/bbs loadfactor=20
        BalancerMember http://192.168.0.138:8003/bbs loadfactor=20
        BalancerMember http://192.168.0.138:8004/bbs loadfactor=20
</Proxy>

上記設定で、/bbs/javascripts/sample.jsをapache側に作成した。ここにアクセスしてみると従来ならmongrel側に飛ばされてファイルが実在しないためエラーになっていたが、今回の設定のおかげで正常にアクセスができ画面にファイルの内容が表示された。

また、/bbs/javascript/effects.jsをリクエストしてみると(これはRails側に実在し、Apache側には存在しない)、mongrel側からデータが帰ってきて従来通り正常に画面にファイルの内容が表示された。

当然ながらどちらにも存在しないファイル/bbs/javascript/effects2.jsをリクエストするとエラーとなった。この事はapacheaccess.logからも確認できた(ただしaccess.log上からはapacheのhtdocs配下にあるファイルなのかmongrel側からのデータを返したのかは分からない)。

"GET /bbs/javascripts/sample.js HTTP/1.1" 200 27
"GET /bbs/javascripts/effects.js HTTP/1.1" 200 38675
"GET /bbs/javascripts/effects2.js HTTP/1.1" 404 667

実際には、RAILS_ROOT/public/(javascripts|stylesheets|images)をapaches側にもってきておくことで、うまく処理できるのではないかと期待している。

あと、幾つか課題が残っているので整理

  • 1サーバで構築する場合、Rails配下のファイルをシンボリックリンクでhtdocs側に見せればApacheが処理できるか?
  • ベーシック認証したいのでREMOTE_USERの環境変数mongrel側に渡せるか?
  • access_logでhtdocs配下のものかmongrel側なのか区別がつくようにできるか?
  • Apacheのパフォーマンスチューニングをどのようにしていくか(mongrelに任せるのと自分で処理するので以下のパラーメータをどの位の値にするか)
Timeout 60
MaxClients 200
ServerSignature Off
ServerTokens ProductOnly
MaxRequestsPerChild 100
MaxSpareServers 45
MaxRequestsPerChild 20
KeepAliveTimeout  10

この辺は解決できれば上級編として書くようにしよう。とりあえず動かすのならここまでできる筈。

補足

mod_proxy_balancerで設定するパラメータで気になっているものをいくつかメモしておく。とくにtimeoutは設定してテストしておきたい。

  • stickysession=JSESSIONIDで、バランサのスティッキーセッションが指定できる
  • maxattempts=1でフェイルオーバー試行最大回数を指定できる
  • timeoutは以下のように書くみたい。ディフォルトだと0秒なので注意が必要かも
ProxyPass /bbs/ balancer://mycluster/ timeout=5