« 2014年5月 | トップページ

2014年8月22日 (金)

複数台WEBサーバのラウンドロビンをサブドメインで固定振り分け

負荷分散構成で、通常はWEBサーバをLBでラウンドロビンさせているけど、特定の操作のあいだはずっと同じサーバに振り分けたいというニーズは、ままあるかと思います。

例えば課金処理のセッションの開始から終了までとか、XSS対策でワンタイムトークンの突き合わせをおこなうとか。

同じIPであれば、L4のLBでもIPのセッション維持で片側に倒すことはできますが、スマホの移動中やテザリングなど、途中でIPが変わる場合は対応できません。

かといってL7のLBでクエリから接続するサーバを振り分けるにも、L7は高いので、予算的に難しいことも多いと思います。

ここでは、Apacheのmod_proxyを使って、サブドメインによって接続するサーバを切り替える、という方法を書きとめておきます。
アプリケーション層から制御できるため、柔軟で、しかも費用がかかりません。

環境:
CentOS 6.5
Apache 2.2.7

構成:
WEBサーバ1 web1 (192.168.1.11)
WEBサーバ2 web2 (192.168.1.12)

ルール:
ドメイン test.com(サブドメインなし) 宛 => web1かweb2のいずれか
ドメイン www1.test.com宛 => web1
ドメイン www2.test.com宛 => web2

イメージ:
Image_2

設定:
@web1


vi /etc/hosts
192.168.1.12 web2 www2.test.com

vi /etc/httpd/conf/httpd.conf
    <VirtualHost 192.168.1.11:80>
        (略)
        <IfModule mod_rewrite.c>
            #プライベートネットワーク以外からのアクセスでwww2.test.com宛の接続はweb2へ
            RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.\d+$
            RewriteCond %{HTTP_HOST} ^www2\.test\.com$
            RewriteRule ^(.+)        %{HTTP_HOST}$1 [C]
            RewriteRule ^www2\.test\.com(.*) http://www2.test.com$1$2 [P,L]
        </IfModule>
    </VirtualHost>

@web2


vi /etc/hosts
192.168.1.11 web1 www1.test.com

vi /etc/httpd/conf/httpd.conf
    <VirtualHost 192.168.1.12:80>
        (略)
        <IfModule mod_rewrite.c>
            #プライベートネットワーク以外からのアクセスでwww1.test.com宛の接続はweb1へ
            RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.\d+$
            RewriteCond %{HTTP_HOST} ^www1\.test\.com$
            RewriteRule ^(.+)        %{HTTP_HOST}$1 [C]
            RewriteRule ^www1\.test\.com(.*) http://www1.test.com$1$2 [P,L]
        </IfModule>
    </VirtualHost>


これで、www1.test.comへのアクセスは常にweb1へ、www2.test.comへのアクセスは常にweb2へ、サブドメイン指定なしのtest.comはラウンドロビン、になります。

デメリットとしては、LBではなくWEBサーバが振り分けるため、リダイレクトによるネットワークコストがかかります。
また、未検証ですが、LB側で重み付けやIPでセッション維持をおこなっていると、LBはweb1へ振り続け、WEBサーバはweb2に振り続け、といったリダイレクトのループが発生してしまうかもしれません。

| | コメント (0) | トラックバック (0)

« 2014年5月 | トップページ