[僕] mod_ext_filter でコンテンツを書き換える

僕ト云フ事

たろマークはてなブックマーク

2009年04月05日

[apache][ec2] mod_ext_filter でコンテンツを書き換える

EC2 はサーバがアメリカ東海岸(とヨーロッパ)にあるため、画像などふんだんに使用していると体感的にも遅く感じます。特に css や javascript ファイルが早くダウンロードできないとその差が大きく出ます。なので、静的なファイルは S3 に置いて CloudFront を使用して配信します。

EC2 を使う場合、大抵は動的なコンテンツだと思うので、ココまでは問題ないと思うのですが、弊社は試しに EC2 を使おうと言うことで http://plucore.jp を置いているのでほぼ全部静的なファイルのため html の書き換えをどうしようかといった問題が発生しました。

そこで apache の mod_ext_filter モジュールを使用して、コンテンツの書き換えを行いました。

ExtFilterDefine static2cdn mode=output intype=text/html \
  cmd="/usr/local/bin/img2cdn.pl"

filter を用意して、Location ディレクティブ内で使用します。

  <Location />
    SetOutputFilter static2cdn
  </Location>

/usr/local/bin/img2cdn.pl はこんな感じ。cdn.plucore.jp は CloudFront へ CNAME で割り当てたサブドメインです。

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
 
my $cdn_host = 'http://cdn.plucore.jp';
 
while (<STDIN>) {
    # src="/load/view.php?a=aHR0cDovL3BsdWNvcmUuanAvY29tbW9uL2ltYWdlL2NvbW1vbi9zaWRlYmFyL3dlYnNlcnZpY2UucG5n"
    # -> src="/load/view.php?a=aHR0cDovL3ZrZ3Rhcm8uanAvY29tbW9uL2ltYWdlL2NvbW1vbi9zaWRlYmFyL3dlYnNlcnZpY2UucG5n"
    s{src="(http://plucore.jp)(.+)(png|jpg|gif|js)"}{src="$2$3"}xmsgi;
 
    # src="/load/view.php?a=aHR0cDovL3ZrZ3Rhcm8uanAvY29tbW9uL2ltYWdlL2NvbW1vbi9zaWRlYmFyL3dlYnNlcnZpY2UucG5n"
    # -> src="/load/view.php?a=aHR0cDovL2Nkbi5wbHVjb3JlLmpwL2NvbW1vbi9pbWFnZS9jb21tb24vc2lkZWJhci93ZWJzZXJ2aWNlLnBuZw"
    s{src="([^:]+)(png|jpg|gif|js)"}{src="$cdn_host$1$2"}xmsgi;
 
    # href="/load/view.php?a=aHR0cDovL3ZrZ3Rhcm8uanAvY29tbW9uL2Nzcy9pbXBvcnQuY3Nz"
    # -> href="/load/view.php?a=aHR0cDovL2Nkbi5wbHVjb3JlLmpwL2NvbW1vbi9jc3MvaW1wb3J0LmNzcw"
    s{href="(.+)(css)"}{href="$cdn_host$1$2"}xmsgi;
 
    print $_;
}
 
1;

これで非 SSL 領域の画像、CSS、Javascript ファイルへのアクセスは CloudFront へ向くようになりました。

後残る問題は CloudFront がカバーしていない SSL 領域です。
CloudFront を使えばいいと思っている方で SSL を使用しようと考えている方は注意が必要です。

そこで、SSL 領域に関しては browser にキャッシュしてもらう方向で考えました。
該当する virtual host 内で Expires を設定することにしました。

  ExpiresActive On
  ExpiresDefault "access plus 4 weeks"
  Header onsuccess append Cache-Control public

なお、Firefox は SSL 領域だと全くキャッシュしないのですが、Header onsuccess append Cache-Control public と設定することで Firefox にもキャッシュしてもらえるようになります。

Expires の設定が間違えたのかと少しハマりましたがこれで解決です。

最初のアクセス時こそ少し重く感じますが、一度アクセスするとキャッシュが効くので体感レベルでは問題がないように思えます。

https://plucore.jp/contact/us.fcgi

ちなみに、plucore.jp は表向き静的なファイルばかりで EC2 的に無駄なようですが、社内向けなものをいくつか立ち上げたりしててあまり無駄になってません。(というかそれがあって、引っ越し先を探してたのもあったり)

追記(2009/04/08 10:33:29)

plucore.jp を全面的に更新するとのことで、一時的に mod_ext_filter を外してます。
cloudfront は1日キャッシュされるので明日まで解除しているかと。

追記(2009/04/09 23:57:41)

cloudfront 戻した。

blog comments powered by Disqus