.htaccessの削除とVirtualDocumentRootのマルチサイト設定でパフォーマンスを向上させる方法

元記事はこちら

By rynop

このチュートリアルは以下の方を対象にしています。
1) 大規模アプリケーションを作っている開発者
2) Apacheを使用していて、Apacheの設定の調整権限を持っている開発者Apacheの .htaccess ファイルはパフォーマンスに打撃を与えるので、ぜひとも使用を控えたいものです。以下に示すチュートリアルでは、CakePHPの機能である「pretty url」を.htaccessを使わずに利用する方法を示します。記事の前半では.htaccessを使用しない方法について説明し、記事の後半ではより複雑な例として一つのApacheで複数のサブドメインを運用する方法について示します。


背景

一般的に、サーバの主設定ファイルにアクセスできない場合を除いて、 .htaccess ファイルの使用は極力避けてください。–apache.org
最初に背景を少し。.htaccessファイルはリソースを食います。有効にすると、毎回のリクエストにおいてドキュメントルート以下の全てのディレクトリでこのファイルを探索します。さらに、探索時に発見された.htaccessファイル内のディレクティブはApacheの設定ディレクティブとメモリ上でマージされます。Apacheのサイトで幾つかの例とさらなる説明があります。
http://httpd.apache.org/docs/2.2/howto/htaccess.html#when

パート1:.htaccessにお別れを

さて、これで問題はお分かりいただけたと思うので、解決しましょう。.htaccessファイルで設定できるものはDirectoryセクションでも設定できます。まず解決法を示し、それから説明します。
Apacheの設定ファイル:

<VirtualHost *:80>
ServerName www.leaguelogix.com
ServerAlias www.leaguelogix.com leaguelogix.com
DocumentRoot /var/www/leaguelogix/app/webroot

Options -Indexes FollowSymLinks

#disable htaccess starting at /
<Directory />
AllowOverride none
</Directory>

<Directory /var/www/leaguelogix/app/webroot/>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

<Files sitemap.xml>
RewriteEngine Off
</Files>
</Directory>
</VirtualHost>

まず、.htaccessファイルの探索と精査を停止します。以下のようにします。

<Directory />
AllowOverride none
</Directory> 

これにより、リクエストのたびにApacheが探索するのを停止することができます。Cakeのプロジェクトから.htaccessファイルを削除しても問題ありませんが、そうしなければならないわけではありません。

DocumentRootを、Cakeアプリケーションのwebrootを指すようにセットアップします。

rewriteルールをセットアップします。

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] 

この記事ではmod_rewriteのパワーや複雑さについて説明しません。概要を示します。これらのルールはファイルまたはディレクトリではないリクエストを、Cakeのwebrootディレクトリのindex.phpに内部的にリダイレクトします。これは、CakeフレームワークのプリティURLマッピングの「マジック」を容易にします。

ここでApacheを再起動します。(sudo /etc/init.d/apache2 restart)

パート2:実装例

簡単ですね?さて、もう少し複雑な(けどタメになる)実際の例を見てみましょう。

好奇心があるなら、leaguelogix.comにアクセスしてみてください。Cakeアプリケーションではないことに気づくでしょう。これは私が30分程度でセットアップしたWordpressのブログです。私のCakeアプリケーションはWebアプリケーションプラットフォームでいくつものサイトで動作しています。一人でたくさんのスポーツ・リーグのサイトを運営管理し、各顧客は自分のWebサイトとドメインを持てるようにしています。

潜在顧客が無料で手早くサイトを作成し、私の製品を試してもらいたいと思いました。それで、Webサイトを持つ代わりに、mysite.leaguelogix.comとサブドメインを持たせることにしたのです。サブドメインごとに別のバーチャルホスト(設定)を作成せずに.htaccessの使用を避けたかったのです。CakePHPプラットフォームは全てのサイトで共通で、サイト固有の設定の調整とルック&フィールがある程度です。

ApacheのVirtualDocumentRootです。パート1で検討した話題が成果を上げます。ここでも、まずコードを示し、それから説明します。

<VirtualHost *:80>
#this handles sitename.leaguelogix.com
ServerName leaguelogix.com
ServerAlias *.leaguelogix.com

Options -Indexes FollowSymLinks

UseCanonicalName Off
VirtualDocumentRoot /opt/leagues/sites/%1/app/webroot

<Directory />
AllowOverride none
</Directory>

<Directory "/opt/leagues/sites/*/app/webroot/">
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/opt/leagues/sites/(.*)/app/webroot/(.*)$ index.php?url=$2 [QSA,L]

<Files sitemap.xml>
RewriteEngine Off
</Files>
</Directory>
</VirtualHost>

パート1で検討した話題を取り上げましょう。

UseCanonicalName Off
VirtualDocumentRoot /opt/leagues/sites/%1/app/webroot 

一つのApache設定を、アクセスされたドメインの複数のドキュメントルートに供給することができます。例:http://mysite.leaguelogix.comにアクセスがあった場合、ドキュメントルートは/opt/leagues/sites/mysite/app/webrootになります。クールでしょ?新しいApacheのバーチャルホストを作成する必要はないし、「お試し」の顧客が来るたびに設定をリロードする必要もないのです。

ここで、トリッキーな部分です。mod_vhost_aliasをロードし、VirtualDocumentRootがパート1で出たシンプルなmod_rewriteディレクティブを無効にします。このままでは条件に合う全てのパスをRewriteRuleに渡します。Cakeのindex.php?urlはこれではうまく動作しません。以下の行でそれが実現できます。

RewriteRule ^/opt/leagues/sites/(.*)/app/webroot/(.*)$ index.php?url=$2 [QSA,L] 

これでwebrootを「はぎ取り」、cakeが必要とするurl($2)を渡します。

A gotcha

ApacheのVirtualDocumentRootはDOCUMENT_ROOTを正しく設定しない(Apacheでずっとオープンになっているバグです)ので、DOCUMENT_ROOTを使用するにはPHPで以下のコードを記述してください。

$_SERVER['DOCUMENT_ROOT'] = str_replace($_SERVER['SCRIPT_NAME'],"",$_SERVER['SCRIPT_FILENAME']);

以上です。お役に立つことを願っています。

注意:これをテストした際に、実際の製品に使用していないことを明記すべきだと感じました。潜在的な誤りがあればご自由にコメントをお寄せ下さい。できるだけお答えします。
Cakeのパフォーマンスを引き出すことに関心がありますか?ではpseudocoderのこちらの記事(英語)も参考にしてください。

One thought on “.htaccessの削除とVirtualDocumentRootのマルチサイト設定でパフォーマンスを向上させる方法”

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です