mod_proxy_balancerで中〜大規模サーバー運用するときの勘所 – (1) mod_proxy_balancerの設定編

Apache2.2から、ロードバランシングをしてくれるmod_proxy_balancer というモジュールが標準添付になりました。

このモジュール、その名前の通り、ApacheレベルでHTTPリクエストをバックエンドのサーバーに振り分けることでロードバランシングをしてくれるモジュールです。

Apacheの公式ドキュメントや試しに入れてみた人のBlogなどは散見されますが、実際の現場で運用している事例というのはまだ無いようです。

そこで、実際にピーク時にover 500 request/secでmod_proxy_balancerなサーバーを運用している経験をふまえ、つまずいた点などを公開していきたいと思います。

まず、mod_proxy_balancerの設定から。よく、httpd.confでこのようになっている設定例を見かけます。

ProxyRequests Off
ProxyPass / balancer://cluster

<Proxy balancer://cluster>
BalancerMember http://192.168.1.1 loadfactor=10
BalancerMember http://192.168.1.2 loadfactor=10
</Proxy>

こう設定した場合、http://example.com/でアクセスした場合は問題なくリクエストが行われたのですが、http://example.com/dir/などサブディレクトリにアクセスした場合、403 forbiddenが返ってきてしまいました。その時のerror_logには以下のように書かれていました。

[Fri Dec 30 22:25:00 2005] [warn] proxy: No protocol handler was valid for the URL /dir/. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

エラーを文字通り受け取れば、mod_proxy_httpなどのmod_proxyのサブモジュールがロードされていないためにエラーが起こっていると思ってしまいがちですが、そうではないのです。(実際にこのエラーが起きたときにはmod_proxy_httpなどはロードされていました)

原因は「ProxyPass /」ディレクティブが、URLに含まれるすべての「/」に適用されてしまうために、このようなエラーになってしまうと言うことでした。

httpd.confの設定を以下のように変えることで解決しました。

ProxyRequest Off
ProxyPass / balancer://cluster/

<Proxy balancer://cluster/>
BalancerMember http://192.168.1.1/ loadfactor=10
BalancerMember http://192.168.1.2/ loadfactor=10
</Proxy>

次回はProxyPassディレクティブに渡すパラメーターについて解説します。

4 thoughts on “mod_proxy_balancerで中〜大規模サーバー運用するときの勘所 – (1) mod_proxy_balancerの設定編”

  1. リクエスト:500over/secという実値での掲載に非常に興味を持ちながら
    「mod_proxy_balancer」について拝見させていただきました。

    非常に嬉しく、また勉強させていただきました。

    一つだけ気になる点が御座いましたので、質問を兼ねて掲載させていただきます。

    それは「SESSION」情報ですが・・・、分散したバックエンドサーバにSESSION情報を
    いかに共有させるのでしょうか?(または、SESSION情報を保持するサーバに的確に次のリクエストも
    受けるようにロジックされるのでしょうか?)

    中〜大規模サーバー運用する場合の勘所として非常に興味がありますので、
    若輩者の質問で恐縮では御座いますが、何卒、ご鞭撻いただければと
    ご回答いただければ幸いです。よろしくお願いいたします。

  2. Booさん、こんばんは。

    セッション情報に関してですが、逆転の発想として、まったくセッションを使わないという手法を使いました。
    幸い、弊社のアプリケーションの場合、セッションを使う必要がありそうだった箇所は最初のID登録ぐらいで、そのほかデータの閲覧などにはセッションが必要なかったので、そういう手法を選択しました。

    仮にセッションを使わざるを得ないという状況だった場合は、mod_proxy_balancerのルーティング機能を使っていたでしょう。
    これはCookieやURLにルーティング情報を持たせておくことで、次回リクエストしたときも必ず指定したサーバーにトラフィックが向くというものです。(つまりサーバー間でセッション情報を共有する必要が無くなります)
    この機能に関しては、以下のURLのstickysessionの項目が詳しいです。
    http://blog.yappo.jp/yappo/archives/000352.html

    ただ、この機能、Apache 2.2.0ではいくつかバグがあったので注意が必要です。
    まず、Cookieにルーティング情報を持たせていた場合、CookieがURLエンコードされているとうまくルーティングが行われませんでした。
    http://issues.apache.org/bugzilla/show_bug.cgi?id=34844

    またURLベースでのルーティング情報の受け渡しもうまくいかないという報告もあります。http://issues.apache.org/bugzilla/long_list.cgi?buglist=37753

    実際にmod_proxy_balancerのルーティング機能を使おうと思ったら、これらのバグが修正された後になると思います。

  3. katzさん、目から鱗でした。

    ありがとうございます。
    stickysession, nofailover, maxattemptsパラメータにより制御出来そうですね。

    http://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html

    教えて頂いたサイトについては、携帯端末を意識した部分は非常に有難いです。
    あと、携帯キャリアによっては機種固有のIDもあった様な気がするので、その
    キーを使用したstickysession設定ができれば、文句なしです。

    http://blog.yappo.jp/yappo/archives/000352.html

    今後、バグレポート通り、正規にFixされれば使用したいと思います。
    ご助言、誠に有難うございます。
    今後とも「勘所」を意識した成果発表を楽しみにしております。

Leave a Reply

Your email address will not be published. Required fields are marked *