YAPC::Asia Tokyo 2010 で LT してきました。以下はその資料(に少し説明を追加したもの)です。
はてなの mod_rewrite 活用事例
- ほぼ reverse proxy
- URLにより用途別のbackendに振り分ける
- 用途によりbackendを分けリソース効率化
- 特定のアクセスをキャッシュサーバーに振る
- URL加工
- Squidにキャッシュさせたいが同一URLで異なるコンテンツを返す場合がある
- →クエリに情報を付加する
- BAN!
便利な半面…
- 増える!
$ cat jp.www.proxy.apache.conf | grep Rewrite | wc -l 179
- テストしづらい! → 一行加えるのも恐ろしい…
Test::Apache::RewriteRules
そこで、 Test::Apache::RewriteRules 。
はてな社内製テストモジュール (id:wakabatan作成) で、Apache の RewriteRule の動作をテストできます。
こちらで公開中です → http://github.com/hatena/perl5-test-apache-rewriterules
しくみ
環境設定
- Apache2 を入れる
- mod_ssl など必要モジュールを入れる
SYNOPSIS
こんな apache.conf があったとして
RewriteRule /foo/(.*) http://%{ENV:ReverseProxyedHost1}/$1 [P,L] RewriteRule /bar/(.*) http://%{ENV:ReverseProxyedHost2}/$1 [P,L] RewriteRule /hoge/(.*) http://external.test/$1 [R,L]
こんなテストが書けます。
use Test::Apache::RewriteRules; use Path::Class qw/file/; my $apache = Test::Apache::RewriteRules->new; $apache->add_backend(name => 'ReverseProxyedHost1'); $apache->add_backend(name => 'ReverseProxyedHost2'); $apache->rewrite_conf_f(file('apache.rewrite.conf')); $apache->start_apache; $apache->is_host_path('/foo/a', 'ReverseProxyedHost1', '/a'); $apache->is_host_path('/bar/b', 'ReverseProxyedHost2', '/b');, $apache->is_redirect('/hoge/z', 'http://external.test/z'); $apache->stop_apache;
書き換え例
my $copied_conf = $apache->copy_conf_as_f($org_file, [ "foo" => "bar", "hoge" => sub { "fuga" }, qr/(foo|bar)/ => "baz$1", ]);
- VirtualHost や CustomLog など関係ないディレクティブも全部消します
- RewriteRule だけの conf ファイルだと簡単です
バックエンドの登録
リバースプロキシ先のバックエンドを登録します。
$apache->add_backend(name => 'BackendMainVIP'); $apache->add_backend(name => 'BackendBotVIP'); $apache->add_backend(name => 'SquidVIP');
RewriteRule で %{ENV:BackendMainVIP} のように環境変数を使える
実際の apache.conf でこのような環境変数を使って記述していない時は、 copy_conf_as_f で書き換える
Apache の起動
$apache->start_apache;
テスト (1) is_host_path
$apache->is_host_path('/' => 'BackendMainVIP', '/');
テスト (2) is_redirect
$apache->is_redirect('/foo' => 'http://example.com/bar');
- is_redirect .. リダイレクトのテスト
- アクセスする path
- リダイレクト先の URL
Test::Apache::RewriteRules::ClientEnvs
特定のクライアント環境を再現するブロックを提供します。
with_docomo_browser { $apache->is_redirect('/n/' => 'http://n/mobile/?&guid=on'); }; with_request_method { $apache->is_host_path('/' => 'BackendMainVIP', '/'); } 'POST';
現在サポートしている環境
Apache の停止
$apache->stop_apache; # (DESTROY でも呼ばれますが)