Web Artisan Blog - ウェブ アルチザン ブログ

mod_proxy_balancerの設定、特にstickysessionについて

Linux・Unix・Apache

2007年01月30日

アフィリエイトから企業サイト分析まで。訪問者の動きがまるわかりのアクセス解析サービス「リサーチアルチザンプロ」

LINEやSkypeみたいなビデオ通話がブラウザだけでできる!オンライン通話サービス「EZ-Interview - イージーインタビュー」

apacheで手軽にロードバランスしてくれるmod_proxy_balancer
今回導入してみたのですが、その際のメモ、特にstickysessionで数日間つまづいたんで、書いておこうと思います。

mod_proxy_balancer導入については、ググりまくって、まず以下のサイト等が参考になりました。

Apache 2.2.0 + mod_proxy_balancer
第5回:サーバの追加とロードバランシング
Apache 2.2でWebサイトをパフォーマンスアップ!


mod_proxy_balancerをインストールして、ProxyPass ディレクティブやらを設定していけば、簡単に導入できます。
あえて詰まった点といえば、以下にありますように、、

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


「balancer://〜」指定の際に、最後にスラッシュ(/)を付けないといけない、というところです。
これは、マニュアルなんかがスラッシュ無しで定義しているので、ついついやっちゃうと思うんですが、これが無いとサブディレクトリ指定したURLでは403エラーが返ってきます。。
ProxyPass / balancer://test/
<Proxy balancer://test/>
BalancerMember http://192.168.1.1/ loadfactor=10
BalancerMember http://192.168.1.2/ loadfactor=10
</Proxy>


このように、単純にバランサーで動かすだけなら、結構簡単に導入できるんです。
で、私が詰まりまくったのはここから。。


ロードバランスさせると、実際は複数のバックエンドサーバーが処理します。
で、私なんかもそうでしたが、「ログインして、セッションを保持して・・」という具合なアプリケーションの場合、複数のバックエンドサーバー間でセッション情報を保持しないといけなくなってきます。
これは、ロードバランスさせた場合に必ずネックになってくることですが、今回の方法としては、「セッション情報をDBに持たせる」か、「mod_proxy_balancerのstickysession」の二点になると思います。

で、まずは「セッション情報をDBに持たせる」方法をやってみました。
ま、これは特にapacheどうこうではなく、アプリケーション側の修正(私の場合はphp)が必要で、これはこれでmod_proxy_balancer上でも理想どおり、複数のバックエンドサーバー間でセッション情報を保持してくれます。
但し、これだとアプリケーションによっては、セッション情報を持った”セッションテーブル”自体に負荷がかかります(毎回、リクエストの度に”セッションテーブル”にアクセスする為)ので、せっかく負荷対策としてmod_proxy_balancerを導入したのに、あんま意味がなくなってきます。。


で、次は「mod_proxy_balancerのstickysession」でやってみました。
stickysessionの仕組みとしては、1回目のリクエストでバックエンドサーバーaにアクセスがあった場合、2回目以降もずっとバックエンドサーバーaにアクセスしにいくという具合に、どのバックエンドサーバーにアクセスしたかを覚えておいて、常にそれにアクセスしていくというやり方です。これであれば、セッション情報をDBに持つように共有化させなくても、ロードバランス環境でうまくセッション情報を保持できます。

導入については、まずapacheの設定が重要になってきますが、これについては以下の記事が非常に参考になりました。

Apache 2.2.0 のロードバランス機能(mod_proxy_balancer)を使いこなす
極めつけはstickysessionです。
これは、CookieもしくはURLの文字列の中に指定したパラメータ名があると、そのパラメータを見てどのサーバを振り向けるかを明示的に指定可能になります。


後、apacheのマニュアルのProxyPass ディレクティブを熟読。。。
結局、ProxyPassディレクティブのstickysessionとrouteの設定が重要だという事になります。

stickysession - バランサーのスティッキーセッション名です。通常はこの値は JSESSIONID や PHPSESSIONID といったものになりますが、この値は バックエンドアプリケーションのサポートするセッションに依存します。
route - ロードバランサで使った場合、ワーカーのルーティングをします。 ルートはセッション ID に付加された値になります。


で、以下の具合に設定しますが、、うまくいかない。。
ProxyPass / balancer://test/ stickysession=PHPSESSID
<Proxy balancer://test/>
BalancerMember http://192.168.1.1/ loadfactor=10 route=a
BalancerMember http://192.168.1.2/ loadfactor=10 route=b
</Proxy>

リクエスト毎に、”192.168.1.1”やら”192.168.1.2”を見に行くんで、全然セッションが保持されません。。。

なんで???と悩んでは以下のサイトを何回も見て、ヒントを探しました。。

PHPでmod_proxy_balancerのstickysessionは使えない?
stickysessionでマニュアルにはめられた件について



で、結局わかったんですが、バックエンドがPHPで「mod_proxy_balancerのstickysession」を使う場合、間違いなくアプリケーション(PHP)側の修正も入ります。
これは、apacheのmod_proxy_balancer設定に合わせた修正になります。

まず上記リンクにもありますが、stickysessionには別にPHPSESSIDを使用する必要はありません。
stickysessionに指定された値について、mod_proxy_balancerはURLかCookieにセットされているものと判断し、探しに行きます。
で、stickysession用に何かしら一意になるidをアプリケーション側で振り、それをCookie、もしくはURLにセットすればいいわけです。
これでまず、stickysessionについて、mod_proxy_balancer側とアプリケーション側で同期が取れました。

次に、routeに指定された値についてですが、mod_proxy_balancerとしては、上記stickysession値にドット(.)とroute値が付加された値を見て、どのバックエンドサーバーにアクセスすればいいかを判断します。

・・つまり、アプリケーション側では、
”stickysession用の何かしら一意になるid”+”ドット(.)”+”各バックエンドサーバー毎のroute値”

をCookie、もしくはURLにセットしてやればいいのです。”各バックエンドサーバー毎のroute値”については、環境変数やらアプリケーション内に定数を用意してやってもいいかも知れません。

例えば以下の設定であると、
ProxyPass / balancer://test/ stickysession=sessid
<Proxy balancer://test/>
BalancerMember http://192.168.1.1/ loadfactor=10 route=a
BalancerMember http://192.168.1.2/ loadfactor=10 route=b
</Proxy>

Cookie、もしくはURLに、
sessid=1234567890.a
※1234567890はアプリケーション側で用意した何かしら一意になるid

というような値がセットされていれば、mod_proxy_balancerはバックエンドサーバーaについてのみアクセスし、正しくstickysessionな動作をします。


後、mod_proxy_balancerについては、balancer-managerにて管理画面で状況を見るのも大事ですね。
apacheが、正しくmod_proxy_balancer周りの設定を認識しているかの確認も出来ますし。
(実は私の場合、VirtualHostディレクティブとか基本的なapache設定の間違いもあったんで、数日悩む羽目になりました・・)

balancer-managerの管理画面が表示されなかった場合は、以下のサイトが参考になります。
mod_proxy_balancerを使ったロードバランシング(格闘編)


mod_proxy_balancerの設定、特にstickysessionについては、元々のapacheのマニュアルの書き方が、なんか微妙??っていうか、文面通りに取ると変にハマル可能性大です。
(route値は、apache側が付加するの?って思ったり。。)

正直、私もstickysessionには、やられました。。。

Web面接に最適。ブラウザだけでビデオ/音声通話ができるオンライン通話サービス。「EZ-Interview - イージーインタビュー」
訪問者録画機能も付いたシンプルで高機能なリアルタイムアクセス解析「リサーチアルチザンプロ」