mod_proxy_balancerメモ

ブログ | 2009/8/26 01:16
まず知っておきたいことはコレ。
「mod_proxy_balancerの設定反映はrestartで」
http://syo.cocolog-nifty.com/freely/2008/10/mod_...

graceful, graceful, graceful, graceful, gracefulしても、stickysessionが反映されず、昨晩は挫折した。

Apache モジュール mod_proxy
http://httpd.apache.org/docs/2.2/ja/mod/mod_prox...
Apache モジュール mod_proxy_balancer
http://httpd.apache.org/docs/2.2/ja/mod/mod_prox...

さて、実践メモ。
VirtualHost単位で、ロードバランスする。
<VirtualHost *:80>
 DocumentRoot "/Users/****/****/public_html"
 ServerName www.*****.com
 ServerAlias *****.com
 ScriptAlias /cgi-bin/ "/Users/****/***/cgi-bin"
 ErrorLog "/var/log/apache2/****_error_log"
 LogLevel emerg
 CustomLog "/var/log/apache2/****_access_log" combined
 
 ProxyPass /balancer-manager !
 <Location /balancer-manager>
   SetHandler balancer-manager
   order deny,allow
   deny from all
   allow from ***.***.*
 </Location>
 
 ProxyRequests Off
 ProxyPreserveHost On
 
 ProxyPass /files !
 ProxyPass /uploader.php !
 ProxyPass /img.php !
 ProxyPass / balancer://cluster/ lbmethod=byrequests stickysession=BALSESSID nofailover=On timeout=1 maxattempts=1
 ProxyPassReverse / balancer://cluster/
 <Proxy balancer://cluster/>
   BalancerMember http://127.0.0.1:8001 loadfactor=10 route=1
   BalancerMember http://192.168.1.2 loadfactor=10 route=2 redirect=1
   BalancerMember http://192.168.1.3 loadfactor=10 route=3 redirect=1
 </Proxy>
</VirtualHost>
こんな感じか。ルートじゃない場合は、
 ProxyPass /test/ balancer://cluster/test/ lbmethod=byrequests stickysession=BALSESSID nofailover=On timeout=1 maxattempts=1
 ProxyPassReverse /test/ balancer://cluster/test/
 <Proxy balancer://cluster/>
   BalancerMember http://127.0.0.1:8001 loadfactor=10 route=1
   BalancerMember http://192.168.1.2 loadfactor=10 route=2 redirect=1
   BalancerMember http://192.168.1.3 loadfactor=10 route=3 redirect=1
 </Proxy>
こんな感じとか。

同一サーバーにも、ポート8001で飛ばしてるので、
Listen 8001
NameVirtualHost *:8001
<VirtualHost *:8001>
 DocumentRoot "/Users/****/****/public_html"
 ServerName *********.com
 ServerAlias www.*********.com
</VirtualHost>
こんなのを書いたり。

ワーカー側(MySQLで言うところのマスターとスレーブは、バランサーとワーカーという呼び方でいいのかしら?)では、普通にVirtualHostを設定する。

ProxyPass /files !
この辺りの書き方は、files以下はスルーするよ(ワーカーに飛ばさないよ)という意味。

で、同じユーザーをあちこちのサーバーに飛ばすと、セッションが維持されなくて、いろいろ不都合が生じる。その設定が「stickysession=BALSESSID」。PHPが勝手につくるPHPSESSIDは、文字列に「.」を持てないからNG。適当な名前のcookieをsetcookie()なんかでつくる。
if(empty($_COOKIE['BALSESSID'])){
 setcookie('BALSESSID','balancer.2',0);
}
とか。「xxxxxxxx.2」のような値にするのが肝。この数字が「route=2」に対応する。

普通のサイトなら、これでrestartすれば動くんじゃないかと思う。

僕の場合、drupal式(今のは知らない)に.htaccessで
<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_HOST} ^xxxxxx.com$ [NC]
 RewriteRule ^(.*) http://www.xxxxxx.com/$1 [L,R=301]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule ^(.*)$ /30maps/public_html/index.php?q=$1 [L,QSA]
</IfModule>
こんなのを書いてるから、balancer-managerの記述を追加。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/balancer-manager
RewriteRule ^(.*)$ /30maps/public_html/index.php?q=$1 [L,QSA]
balancer-managerは、一時的に分散させる比率を変えられたりするので、あった方が面白い。

分散を考慮して、サイトのプログラムもやや修正。画像の表示やファイルのアップロード関係は、どこかのサーバーにまとめる必要がある
 ProxyPass /uploader.php !
 ProxyPass /img.php !
これがそのあたり。これらのURLはマスターへの意。uploaderなんかは、ログインしてるかどうかの判別が必要だから、DBを叩く。


不具合も出そうだけれども、次のステップに入ったということでしばらく様子見。
▼追記 2009/8/27 01:59
IPの取得に使っている
$_SERVER['REMOTE_ADDR']
が、バランサーのIPになってしまう。

PHP5.3の省略三項演算子で、
$host = @$_SERVER['HTTP_X_FORWARDED_FOR'] ?: $_SERVER['REMOTE_ADDR'];
こうすることにした。

携帯adsenseを見たら、アクセスがゼロになっていて、タイミング的にこれだろうということで検索をしたら、
「モバイル向けAdsenseが、表示回数やクリック数がカウントされない件。」
http://blog.mynet.co.jp/hirashima/2008/11/adsens...
で、スバリヒット。

上記サイトを参照に下記のようにして、カウントが再開された。
//$GLOBALS['google']['host']=$_SERVER['HTTP_HOST'];
//$GLOBALS['google']['ip']=$_SERVER['REMOTE_ADDR'];
$GLOBALS['google']['host']= @$_SERVER['HTTP_X_FORWARDED_HOST'] ?:$_SERVER['HTTP_HOST'];
$GLOBALS['google']['ip']= @$_SERVER['HTTP_X_FORWARDED_FOR'] ?: $_SERVER['REMOTE_ADDR'];

//$GLOBALS['google']['url']=$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$GLOBALS['google']['url']=$GLOBALS['google']['host'] . @$_SERVER['REQUEST_URI'];

ところで、
モバイルサイト用のGoogle analyticsは、出ないのだろうか。

Rottel内コンテンツ

ユーザー一覧

Rottelとは?
利用規約
開発飲料
利用者の声
ヘルプ
close