apache2でロードバランサ

とあるAPIを公開する際に、ロードバランサを使って複数台のサーバで並列処理する必要があった。

ロードバランサは、日本語では負荷分散装置となるのだろうか、外部からのアクセスに対してあるサーバを入り口として、同じ機能を持つ複数のサーバにそのアクセスを転送・分散する機能のこと。これをapache2のproxy_balancerで実現してやろうという話なのだが、この話題はいろいろな参考サイトが存在するだけでなく、apache2以外にも様々なソフトで実現できる。ここでは、とにかく簡単に実現する方法を載せている。

まず、ユーザがアクセスする先を入り口のサーバに設定する。仮にhttp://hoge.comとして公開したとしよう。公開するのは入り口のサーバだけで良く、他のサーバは入り口のサーバからアクセス可能であればローカルでもグローバルでも良い。次に、ユーザがhttp://hoge.comにアクセスすると、入り口のサーバがサーバ1〜3のうち一番負荷の少ないサーバに飛ばす。つまり、ユーザが実際に閲覧するサイトは、サーバ1〜3のうちのどれかが提供したものだが、ユーザ側がそれを意識する必要はない。

サーバ1〜3は、表示したいサイトを、apacheだろうが何だろうが、とにかくサービスできるようになっていれば良く、ロードバランス先であるからといって特別な設定があるわけではない。

入り口のサーバのapacheにはロードバランサの設定をしなければならない。まず、いくつかのapacheモジュールを使えるようにする。以下はUbuntu/debianでの設定例だが、RedHat系でもそれほど変わらないと思う。

apache2以外に必要なパッケージは、libapache2-mod-proxy-htmlだけ。これをaptでインストールしておく。肝心なのはモジュールを有効化しておくこと。

# a2enmod proxy
# a2enmod proxy_http
# a2enmod proxy_html
# a2enmod proxy_balancer

proxy_html以外は、apache2-commonに同梱されている。有効化すると、apache2をrestartしろと言ってくるがひとまず後回しで構わない。ちなみに、これらのうち一つでも有効化できなければapache2のバージョンが古い可能性が高い。apache2を新しくするか、あきらめよう。

具体的な設定は、/etc/apache2/site-available/defaultの<VirtualHost *:80>内に以下のように記述する。ProxyPassは、他のサーバに飛ばす機能だが、飛ばす先にロードバランサを設定するようなイメージ。

<VirtualHost *:80>
    ...なんやかんや他の設定...
    ProxyPass /balancetest/ balancer://balance/ stickysession=sesid
    ProxyPassReverse /balancetest/ balancer://balance/ stickysession=sesid
    <Proxy balancer://balance/>
        BalancerMember http://www.google.com loadfactor=10
        BalancerMember http://www.yahoo.com loadfactor=10
    </Proxy>
</VirtualHost>

設定ファイルを書き終わったらapacheをリスタートする。service apache2 restartでも、/etc/init.d/apache2 restartでも良いが、reloadではダメなよう。この設定では、入り口のサーバのアドレスをhttp://hoge.com/としたとき、http://hoge.com/balancetest/にアクセスすると、googleかyahooのうち負荷の低い方が表示される。リロードし続けるとほぼ交互に表示されるはず。どちらかしか表示されない、もしくは表示されない、エラーになる場合は何かが間違っている。飛ばす基準の設定もあるが、割愛。

ちなみに普通のProxyPassはこんな感じ。

<VirtualHost *:80>
    ...なんやかんや他の設定...
    ProxyPass /trip/ http://server/
    ProxyPassReverse /trip/ http://server/
</VirtualHost>

こう設定すると、http://hoge.com/trip/にアクセスすると、apache2がhttp://server/にアクセスしに行き、その内容がユーザには表示される。/trip/以下の文字列はそのまま引き継がれるので、http://hoge.com/trip/cgi/test/index.cgiとアクセスすれば、http://server/cgi/test/index.cgiに飛ばされる。パスの設定をきちんとしておかないとややこしいことになる。

以下はサーバ1〜3に飛ばすときの設定。サーバ3だけアドレスが異なる場合を想定。まず、それぞれのサーバに直接アクセスして、想定した通りの表示になっているかを確認する。その後、http://hoge.com/balancetest/にアクセスすれば良い。

<VirtualHost *:80>
    ...なんやかんや他の設定...
    ProxyPass /balancetest/ balancer://balance/ stickysession=sesid
    ProxyPassReverse /balancetest/ balancer://balance/ stickysession=sesid
    <Proxy balancer://balance/>
        BalancerMember http://server1/api/ loadfactor=10
        BalancerMember http://server2/api/ loadfactor=10
        BalancerMember http://server3/test/api/ loadfactor=10
    </Proxy>
</VirtualHost>

ProxyPass単体のときと同じで、http://hoge.com/balancetest/index.cgiにアクセスすると、http://server1/api/index.cgiやhttp://server3/test/api/index.cgiにアクセスされる。

うまく設定できるまでは、どこに飛ばされたか分かるように、飛ばし先のCGIやHTMLにサーバ名を表示するようにしておくと良い。

コメントを残す

メールアドレスが公開されることはありません。