apache2 + mod_proxy_balancer

はじめに

HAS プロジェクトで、これから apache2 + mod_proxy_balancer + thin + Ruby on Rails でサービスを提供する。
そこで apache2 + mod_proxy_balancer で Web サービスを提供できるようにする。
まずは、 mod_proxy_balancer について調査する。概要や設定、TIPS など、 Web で調べられる情報を収集する。そして、実際に設定し、サービスを稼働できるようにする。

mod_proxy_balancer

まずは一時情報を確認する。
mod_proxy - Apache HTTP Server Version 2.2mod_proxy - Apache HTTP サーバ バージョン 2.2 を読む。

特定のプロキシの機能を使いたい場合は、mod_proxy と 該当するモジュールを組み込む必要がある。

Do not enable proxying with ProxyRequests until you have secured your server.

ようするに ProxyRequests を有効な状態にしなければいいのね。

A reverse proxy is activated using the ProxyPass directive or the [P] flag to the RewriteRule directive. It is not necessary to turn ProxyRequests on in order to configure a reverse proxy.

ようするに、ProxyPass を有効にすればよくて、ProxyRequests は有効にするな!!ということですね。

Reverse Proxy

ProxyRequests Off


Order deny,allow
Allow from all

ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar

参考になります。

AllowCONNECT ディレクティブ
...
CONNECT を使用するには、mod_proxy_connect がサーバに組み込まれていなければならないことに注意してください。

SSL で通信するときは上記の設定を有効にしておく。

サブディレクトリをリバースプロキシしたくないときに ! は 役に立ちます。例えば、

ProxyPass /mirror/foo/i !
ProxyPass /mirror/foo http://backend.example.com

は /mirror/foo/i を除く /mirror/foo へのすべてのリクエストを backend.example.com にプロキシします。

順番は重要です。一般的な ProxyPass ディレクティブの前に 除外ディレクティブを置く必要があります。

サービスを複数運用する予定なので、上記の設定は必須です。

2.1 の機能で、バックエンドサーバとの接続にプールされたコネクションを 使えるようになりました。key=value 形式のパラメータで このコネクションプーリングの調整ができます。Hard Maximum のデフォルト値は、有効になっている MPM でのプロセス当たりのスレッド数と 同じ数のコネクション数です。prefork MPM では通常は 1 で、worker MPM では ThreadsPerChild で調整されます。

min の設定で、バックエンドサーバとの間に何本のコネクションを 常時開くかが決まります。Soft Maximum smax の数に 達するまで必要に応じてコネクションは生成されます。smax を超えた数のコネクションは、生存時間 ttl で切断されます。 バックエンドサーバと Hard Maximum max の数以上のコネクションを 生成することはありません。

ProxyPass /example http://backend.example.com smax=5 max=20 ttl=120 retry=300

これも重要そうだね。不要なサービスは起動させないようにしないと、メモリがいくらあっても不足してしまう。

ProxyPassReverse ディレクティブ
...
このディレクティブは Apache に HTTP リダイレクト応答の Location, Content-Location, URI ヘッダの調整をさせます。
...
例えば、ローカルサーバのアドレスが http://example.com/ だとします。すると

ProxyPass /mirror/foo/ http://backend.example.com/
ProxyPassReverse /mirror/foo/ http://backend.example.com/
ProxyPassReverseCookieDomain backend.example.com public.example.com
ProxyPassReverseCookiePath / /mirror/foo/

という設定をすると、http://example.com/mirror/foo/bar へのローカルリクエストが http://backend.example.com/bar へのプロキシリクエストに内部でリダイレクトされるだけではありません (これは ProxyPass の機能です)。backend.example.com が送るリダイレクトの面倒もみます。http://backend.example.com/barhttp://backend.example.com/quux にリダイレクトされたとき、 Apache は HTTP リダイレクト応答をクライアントに送る前に、 http://example.com/mirror/foo/quux に変更します。 URL を構成するのに使われるホスト名は UseCanonicalName の設定に応じて選択されることに 注意してください。

これも設定しておかないと、まずいような気がする。

さて、そろそろ設定を開始するかな。

Apache の設定

まずは設定の方針を明確にする。

  • Radiant CMS は thin で運用する。
  • 3 プロセス動かし、ポートは 10000 から 10002 まで使用する。
  • リバースプロキシで / へのアクセスを Radiant CMS へ送る。
w101$ sudo a2enmod proxy            
  Enabling module proxy.
  Run '/etc/init.d/apache2 restart' to activate new configuration!

w101$ sudo a2enmod proxy_http
  Considering dependency proxy for proxy_http:
  Module proxy already enabled
  Enabling module proxy_http.
  Run '/etc/init.d/apache2 restart' to activate new configuration!

w101$ sudo a2enmod proxy_balancer
  Considering dependency proxy for proxy_balancer:
  Module proxy already enabled
  Enabling module proxy_balancer.
  Run '/etc/init.d/apache2 restart' to activate new configuration!

(proxy_http を有効にしていなくてはまってしまいました。)

w101$ f=/etc/apache2/sites-available/default
w101$ sudo cp -a -i ${f} ${f}.orig
w101$ sudo vi ${f}
w101$ diff -u ${f}.orig ${f}
w101$ cd /var/share/nfs/radiant
w101$ sudo -u www-data thin --address localhost --port 10000 --adapter rails --chdir /var/share/nfs/radiant --environment production --daemonize --user www-data --group www-data --servers 3 config --config /var/share/nfs/radiant/config/thin.cfg
  >> Wrote configuration to /var/share/nfs/radiant/config/thin.cfg
w101$ sudo thin --config /var/share/nfs/radiant/config/thin.cfg start
  Starting server on localhost:10000 ... 
  Starting server on localhost:10001 ... 
  Starting server on localhost:10002 ... 
w101$ sudo /etc/init.d/apache2 restart
  Restarting web server: apache2 ... waiting .

これでできた。