ApacheLBをやってみる

○ やること

Web2台、NFS構成で、入り口のロードバランサーをApache2.2系のmod_proxy_balancerを使って構築してみる。

そのとき、ApacheLBにもNFSからコンテンツ領域をマウントしておき、静的コンテンツはバックエンドのWebには振らずに、LB上で返すようにする。

○ 構成

|----| LB |---+---| Web01 |
       |
       +---| Web02 |
       |
       +---|  NFS  |

○ ApacheLB用のコンパイルオプション

"./configure" \
"--prefix=/usr/local/apache2_worker" \
"--with-mpm=worker" \
"--enable-cache" \
"--enable-deflate" \
"--enable-disk-cache" \
"--enable-headers" \
"--enable-mem-cache" \
"--enable-proxy" \
"--enable-proxy-balancer" \
"--enable-rewrite" \
"--enable-so" \
"--enable-ssl" \
"--enable-substitute" \
"--disable-asis" \
"--disable-auth-digest" \
"--disable-authn-anon" \
"--disable-authn-dbd" \
"--disable-authn-dbm" \
"--disable-authn-default" \
"--disable-authz-dbm" \
"--disable-authz-default" \
"--disable-authz-owner" \
"--disable-cgid" \
"--disable-dav" \
"--disable-dav-fs" \
"--disable-dbd" \
"--disable-dumpio" \
"--disable-expires" \
"--disable-ext-filter" \
"--disable-ident" \
"--disable-imagemap" \
"--disable-include" \
"--disable-info" \
"--disable-negotiation" \
"--disable-speling" \
"--disable-userdir" 

なげぇ。
不要なモジュールは省き、必要なモジュールは静的に組み込んでみる。
静的コンテンツのみ扱うので、ついでにMPMはworkerに。

○ 各種設定

まず、/etc/hostsにバックエンドWebの適当なホスト名と、IPアドレスを関連付けしておく。

# vi /etc/hosts
exms.web01 192.168.0.11
exms.web02 192.168.0.12

つづいてー、Apacheの設定ファイルにLB設定書きます。

<VirtualHost ***.***.***.***:80>
    ServerName   example.com

    DocumentRoot /home/example/htdocs
    CustomLog    /var/log/httpd/example/access_log combined
    ErrorLog     /var/log/httpd/example/error_log

    ProxyRequests Off
    ProxyPassMatch !\.(png|jpe?g|gif|css|js|ico) balancer://exms/ timeout=2

    ProxyPreserveHost On
    RequestHeader set X-SSL-FLAG %{HTTPS}s

    ProxyPassReverse / http://exms.web01:80/
    ProxyPassReverse / http://exms.web02:80/

    <Proxy balancer://exms/>
        BalancerMember http://exms.web01:80 loadfactor=10
        BalancerMember http://exms.web02:80 loadfactor=10
    </Proxy>

    RewriteEngine on
    RewriteCond %{REQUEST_URI} !\.(png|jpe?g|gif|css|js|ico)
    RewriteRule ^/(.*)$ balancer://exms/$1 [P,L]

    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|mogemoge.com|hogehoge.jp|i"

    CacheRoot /usr/local/apache2_worker/cache
    CacheIgnoreCacheControl On
    CacheIgnoreHeaders Set-Cookie
    CacheEnable disk /
    CacheDefaultExpire 600
    CacheDirLevels 3
    CacheDirLength 3

    ErrorDocument 503 /sorry/503.html
    Alias /sorry/ /usr/local/apache2_worker/htdocs/

    <Directory /home/example/htdocs>
        Order deny,allow
        Deny  from all
        Allow from ***.***.***.***
   </Directory>
</VirtualHost>

一応、いろいろ意味があったりします。
ProxyRequests … フォワードプロキシとしては利用しないので、Offで。

ProxyPassMatch … 拡張子が.png .jpeg .jpg .gif .css .js .ico以外だったらバックエンドのWebにぶっ飛ばし。

ProxyPreserveHost … バックエンドのWebにHostヘッダ情報を渡す( $ENV{HTTP_HOST}がユーザからのリクエスト時のホスト名になる)。Offにしたら、$ENV{HTTP_HOST}はexms.web01とかになりますので、ご注意を。

RequestHeader set X-SSL-FLAG %{HTTPS}s リクエストスキームがhttp://だったら0、https://だったら1がセット。

Rewriteで指定拡張子以外だったらリバーーースプロキシィイイイ。

AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|mogemoge.com|hogehoge.jp|i"
 これ、実はLBとしては必要ないけれど、結構便利なのでテストで導入。
 レスポンスボディ内の指定文字列を置換してくれます。
 
 上記の例だと、mogemoge.com を hogehoge.jp に置換してくれてます。
 これはリンク先を別ホストに変更したいけど、ページいじりたくねぇって時にパゲ便利。
 
Cache〜系はディスクキャッシュを使ってます。
NFSからいちいち画像をとりにいかんでも、いっかいとったらキャッシュできるようにすれば環境に優しい、ド・エコLBになること間違い無し。

…と、言いたいところですが、まだまだ実験段階。
キャッシュ系はサービスにも影響するので、本導入はまだまだ検証が必要ですなぁ。

最後に、バックエンド側のWebが全て落ちた場合、Apacheステータスコード503を返します。なので503だったら、Sorryページ(混んでます、すんません的な)を見せるために、ErrorDocumentでそれ用のページを指定しています。
AliasはHTMLをドキュメントルート外に置きたかっただけなので、設定しただけで。
必要ないっちゃぁ必要なし。

っということで。