Entry: mod_perlにしてみた
mod_perlにしてみた
このブログをmod_perl対応にしてみた。以前からspeedyCGI対応だったので、結構あっさりでした。これでレンタルサーバに以降できそうな気がしてきた。
ただ、まだ設定がまずいのか、あまりパフォーマンスはよくない。効果あったりなかったりとムラがある。そして、効果あるときでもspeedyに負けている。この辺は追々チューニングしていこう。
あと話は変わりますが、最近、CPAN Authorになりました。そんな世界に発信するほどのネタなんてなかったんですが、何事も経験と思って半ば強引に、improvedな車輪をいくつかアップしてみました(ごめんなさい)。おかげで、基礎的なモジュールの作り方から、様々なお作法までざっと習得することができました。
そして、今さらCPANすげーってことを知りました。どこの馬の骨とも分からない僕のような者が作った、見るからにパッとしないモジュールでも、半月で370件ものテストレポートが届き、30のプラットフォームでの動作確認がとれちゃったり。
自分で作ったもの以外は信用できない、とか、これも勉強のうち、とか言って、車輪の再発明をするのも、そろそろ卒業しようと思いました。
Entry: speedycgiすげかったんだ
speedycgiすげかったんだ
キャッシュするとアクセスログが記録できなかったのを改善。キャッシュにアクセスログ系のテンプレート関数を書きこんじゃって、中間コード的な仕様にする。そしたら、以前に書いたエントリー中のサンプルコードとデリミタがバッティング。しばらく悩む。
そして解決。いずれにしても、キャッシュ機能自体、今のところ全く効果なし。てか、効果測定する方法がわからない。倍返しで速くなると何故か確信してたのに・・。しかも、クローラーに舐められた後はキャッシュファイルだけで1000ページも生成されてディスクの無駄。なんて考えると、余裕で速度10倍とかはじき出すspeedycgiってスゴすぎるな。そろそろ自宅サーバーもやめてレンタルサーバーにしようと思ったりもするけど、speedycgiがないことだけが憂鬱。
Entry: 画像サムネイル自動生成機能つけてみた
画像サムネイル自動生成機能つけてみた
高速化第二弾。もはやサーバ側で何やっても大差ない気がしてきました。体感速度の重さはCSSが汚すぎるのと画像がデカ過ぎる辺りに問題が。最近のエントリーに添付する画像は全部、横800pxという馬鹿みたいにデカいのをブラウザに縮小させてたんですが、150pxのサムネイルを自動生成するようにしました。
mod_rewriteで気の利いた仕組みにしてみました。sample.jpgというのが元画像。sample.jpg?x=150とすると横150pxにして出力する。実はここまでは数日前から運用してたのですが、Perlの処理が重いのか、SpeedyCGIに任せて起動時間削減しても逆に重くなりました。という訳で、今日からキャッシュ機構を取り入れ、2度目以降のアクセス時にはPerlを一切使わない仕組みにしました。まだちゃんと動作してるか不安なので、詳細は後日。
- 2007.7.20追記 -
resize.cgi。実際は画像以外も扱うので、ちょっとだけ複雑。
#!/usr/bin/perl -w ### ----------------------------------------- ### ディレクトリ構造 ### ----------------------------------------- ### 画像ルート ### ┣ resize.cgi ### ┣ image1.jpg ### ┣ image2.jpg ### ┣ image3.gif ### ┣ ... ### ┣ キャッシュディレクトリ ### ┣ image1.x=100.jpg ### ┣ image2.y=100.jpg ### ┣ image3.x=100.gif ### ┣ image3.x=100&y=200.gif ### ┣ ... ### ----------------------------------------- ### 初期設定 ### ----------------------------------------- my $org_dir = ''; my $cache_dir = 'cache'; my $default_width = undef; my $default_height = undef; my $max_width = 800; my $max_height = 800; ### ----------------------------------------- use strict; use warnings; use HTTP_util; # 自前 use Image::Magick; our %QUERY = &HTTP_util::read_query($ENV{'QUERY_STRING'}); $QUERY{'f'} or die 'file not found'; my ($name, $ext) = ($QUERY{'f'} =~ /^(.+)\.([^.]+)$/); my $new_query = ($ENV{'QUERY_STRING'} =~ /^f=.+?&(.+)/)[0]; my $cache_path = sprintf('%s/%s.%s.%s', $cache_dir, $name, $new_query, $ext); &binary_out($cache_path) or &resize_image($cache_path); ### ----------------------------------------- ### 汎用バイナリ出力 ### ----------------------------------------- sub binary_out { if (open(IN, $_[0])) { print &HTTP_util::get_http_header(tpl_name => $QUERY{'f'}); binmode(IN); binmode(STDOUT); read(IN, my $buf, -s $_[0]); print $buf; close(IN); return 1; } return 0; } ### ----------------------------------------- ### 画像リサイズ出力 & キャッシュ出力 ### ----------------------------------------- sub resize_image { ### ソース my $org_path = $org_dir. './'. $QUERY{'f'}; -e $org_path or die 'file not found'; my $image = Image::Magick->new; $image->Read($org_path); my ($width, $height, $format) = $image->Get('width', 'height', 'magick'); ### 引数取得 my $target_width = ($QUERY{'x'} or $default_width or 0); my $target_height = ($QUERY{'y'} or $default_height or 0); ### アスペクト比保持 $target_height ||= ($height * $target_width) / $width; $target_width ||= ($width * $target_height) / $height; ### 上限判定 $target_width = $max_width if ($target_width > $max_width); $target_height = $max_height if ($target_height > $max_height); ### 四捨五入と0回避 $target_width = (int($target_width + 0.5) or 1); $target_height = (int($target_height + 0.5) or 1); ### リサイズ $image->Resize(width => $target_width, height => $target_height); ### ヘッダ出力 print &HTTP_util::get_http_header(tpl_name => $QUERY{'f'}); ### ----------------------------------------- ### ユーザー出力 ### ----------------------------------------- binmode(STDOUT); $image->Write($format. ':-'); ### ----------------------------------------- ### キャッシュ出力 ### ----------------------------------------- if (open(CACHE, "> $_[0]")) { binmode(CACHE); $image->Write(file => \*CACHE, filename => $cache_dir); close(CACHE); } undef $image; return 1; }
画像ルートに.htaccess。通常はそのままファイルにアクセス。クエリー指定があるならキャッシュファイル名を生成して書き換え。ファイルの存在確認のうえ、なければresize.cgiに書き換え。一応動いてるっぽいけど、かなり自信なし。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !cache/[^\/]+$
RewriteCond %{REQUEST_FILENAME} !resize.cgi$
RewriteCond %{QUERY_STRING} .
RewriteRule (\w+)\.(\w+)$ cache/$1.%{QUERY_STRING}.$2 [E=ORG:$1.$2,C]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) ?f=%{ENV:ORG}&%{QUERY_STRING}
Entry: SpeedyCGIで高速化してみた
SpeedyCGIで高速化してみた
ブログがあまりに重いので、SpeedyCGIというものを導入してみました。apacheモジュールのほうです。最初、mod_perlにしようと思ったのですが、導入が大変なうえに、ネット上のベンチマークでSpeedyCGIのほうが上回っていたので、こちらにしました。名前はダサいけど優れモノです。リモートのFirefoxで計測して3倍速以上になりました。ただし、どこかに予期せぬバグが潜んでる可能性も。
いくつかある高速化の仕組みの中で、これが一番、導入が簡単と定評だったのですが、結構、ソースの変更が必要でした。ただ、SpeedyCGI専用の書き方というよりは、より汎用的な書き方になった感じなので悪くない。
インストール手順。設定はapache2.confで固定、使用の有無はhtaccessで個別に指定。非対応のCGIもあるので。
# apt-get install libapache2-mod-speedycgi # cat apache2.conf <IfModule mod_speedycgi2.c> SpeedyMaxruns 10 SpeedyMaxBackends 10 SpeedyTimeOut 3600 </IfModulev> $ cat ~/www/blog/.htaccess AddHandler speedycgi-script .cgi
CGIソースの変更。グローバル変数の初期化などは大方、そんなもんだろうと思って適当に片付けたのですが、下記の2点の発見に手こずりました。おかげで、フォームデコード処理レベルからぶった切って検証するはめに。
- $^T(スクリプト起動時刻)は保持される --> グローバル変数$main::boot_time = time()で代用
- ・sysreadがなぜか機能しない --> sysreadである必要ないのでreadに変更
Subscribe to my RSS feed