2008/07/29(Tue)SpeedyCGIが大量起動
2008/07/29 0:47
ごらんのとおり、このModus Operandiが公開blogである。
色々とadiary.conf.cgiの設定も違うから、ファイルを別個に分けてあるのだけど、どーも、moのほうだけ開くのが遅い。遅い。bf:遅い。
特にひどいのは記事をSubmitするときとか、管理メニューを開くとき。10秒くらい待たされることが多々。red:これはひどい。
何でだろうと思って、ターミナルを開くとこれまた重い。
Load Averageが5とか10とかになってやんの。どおりで重いわけだ……。
topをかけてみると、こんな感じ。*1
top - 00:51:48 up 88 days, 8:29, 1 user, load average: 3.06, 2.15, 1.80 Tasks: 218 total, 5 running, 213 sleeping, 0 stopped, 0 zombie Cpu(s): 98.5%us, 1.5%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 515212k total, 349296k used, 165916k free, 8944k buffers Swap: 787176k total, 388272k used, 398904k free, 58780k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 18019 apache 20 0 30468 24m 2816 R 25.8 4.9 0:29.53 speedy_backend 17995 apache 20 0 29632 23m 2816 R 25.3 4.8 0:25.77 speedy_backend 18047 apache 20 0 28812 23m 2816 R 25.3 4.6 0:18.32 speedy_backend 17982 apache 20 0 28952 23m 2816 S 13.6 4.6 0:20.50 speedy_backend 18179 apache 20 0 25420 19m 2780 R 7.3 3.9 0:03.92 speedy_backend 8566 apache 20 0 3912 1448 1444 S 0.0 0.3 0:00.01 speedy_backend 8567 apache 20 0 25904 7580 2936 S 0.0 1.5 0:13.11 speedy_backend 16712 apache 20 0 26096 5728 2180 S 0.0 1.1 0:00.18 httpd 16719 apache 20 0 26100 5708 2176 S 0.0 1.1 0:00.13 httpd 17282 apache 20 0 3912 1832 1456 S 0.0 0.4 0:00.02 speedy_backend 17356 apache 20 0 26120 6804 3204 S 0.0 1.3 0:00.12 httpd 17647 apache 20 0 28352 9236 3216 S 0.0 1.8 0:00.66 httpd 18055 apache 20 0 26120 6784 3204 S 0.0 1.3 0:00.02 httpd 18155 apache 20 0 3640 800 652 S 0.0 0.2 0:00.00 adiary.speedy.c 18158 apache 20 0 3640 804 656 S 0.0 0.2 0:00.00 adiary.speedy.c 18159 apache 20 0 3640 808 656 S 0.0 0.2 0:00.00 adiary.speedy.c 18160 apache 20 0 3640 808 656 S 0.0 0.2 0:00.00 adiary.speedy.c 18161 apache 20 0 3640 796 652 S 0.0 0.2 0:00.00 adiary.speedy.c 18162 apache 20 0 3640 808 656 S 0.0 0.2 0:00.00 adiary.speedy.c 18163 apache 20 0 3640 808 656 S 0.0 0.2 0:00.00 adiary.speedy.c 18164 apache 20 0 26096 5076 1552 S 0.0 1.0 0:00.01 httpd 18171 apache 20 0 3640 792 652 S 0.0 0.2 0:00.00 adiary.speedy.c 18177 apache 20 0 3640 800 652 S 0.0 0.2 0:00.00 adiary.speedy.c 18178 apache 20 0 3640 796 652 S 0.0 0.2 0:00.00 adiary.speedy.c 18185 apache 20 0 3640 796 652 S 0.0 0.2 0:00.00 adiary.speedy.c 19629 apache 20 0 28716 7916 4552 S 0.0 1.5 0:05.22 httpd 19695 apache 20 0 28392 9724 4648 S 0.0 1.9 0:06.15 httpd 19726 apache 20 0 27052 7948 4444 S 0.0 1.5 0:03.95 httpd 19731 apache 20 0 28716 9468 4424 S 0.0 1.8 0:05.44 httpd 19744 apache 20 0 27940 9.9m 4720 S 0.0 2.0 0:04.48 httpd 19754 apache 20 0 27556 9748 4720 S 0.0 1.9 0:04.38 httpd 19760 apache 20 0 28376 9.8m 4608 S 0.0 2.0 0:06.34 httpd 19787 apache 20 0 27836 9.9m 4652 S 0.0 2.0 0:04.68 httpd 19813 apache 20 0 28696 9372 4296 S 0.0 1.8 0:05.04 httpd 22168 apache 20 0 28144 9284 4480 S 0.0 1.8 0:11.31 httpd 22170 apache 20 0 28136 8912 4624 S 0.0 1.7 0:08.38 httpd 22173 apache 20 0 27276 9036 4352 S 0.0 1.8 0:10.07 httpd 22175 apache 20 0 28720 8184 4648 S 0.0 1.6 0:14.24 httpd 26275 apache 20 0 28128 8724 4004 S 0.0 1.7 0:09.27 httpd 31115 apache 20 0 28708 9660 4476 S 0.0 1.9 0:09.31 httpd
apacheさんが大量にspeedyを起動しちゃって、backendが追いついていない感じ。
backendがアホみたいにCPUを食いつぶしているのが原因だろうと思って、一時的にspeedyの呼び出し引数に"-- -M5 -r10 -t3600"とか付けてみたんだけど、全然状況変わらず。
一方、非公開blogの方では同一バージョンを使用しているのに、全く
こういうことがない。speedyは常時2個くらい起動しっぱなしで、これ以上増えない。動作も快適。
が、moの方はリンクをクリックした拍子とかに10個も20個もバババーっと増えるのである。しばらくすると消える。
単にアクセス数の問題か……?否か……。
記事数ならば非公開blogの方がmoの10倍弱はある。
ちょっと時間ができたら双方を詳しく比べてこの問題を解決したいところである。今は時間がない。
2008/07/17(Thu)変数の展開の展開
2008/07/17 4:21
やりたいこと
「何らかの処理の結果、ある文字列が得られたとする。その文字列と同じ名前の変数名を取得したい」具体的には、リソースファイルに"この結果は$resultになります"のように埋め込んでおき、スクリプト実行時に変数$resultを代入して、"この結果は25になります"のように表示させたいわけだ。
今まで使っていた手法
リソースファイルをPerl化してしまってrequireすれば、同じ名前空間の変数で、すでに定義されているものは自動展開されるという仕様を使っていた。埋め込む変数名ごとに正規表現で置換するような面倒な手法に比べると楽にできていたのだが、Perl化する手間とフォーマットが崩れるのが欠点。
拡張子がplになってしまうので*1、HTMLファイルのテンプレートを書いていたところで、vimなんかで読み込むとPerlの色づけしかしてくれなくて不便なのである。
実際どんな手順かというと、リソースファイルとして、
#!/usr/local/bin/perl # requireされるとき自動展開するためにダブルクォートにしておく $tmp = << "_EOM_"; この結果は$resultになります _EOM_ # requireのため、1;は削除できない(結構面倒な仕様) 1;という代入だけを行うスクリプトを別途用意し、
呼び出し側として、
#!/usr/local/bin/perl $result = 5*5; require 'resource.pl'; print $tmp;のような手順を踏まなくてはいけない。自動展開されるとはいえ、結構めんどい。
また、$tmpや$resultという変数名は両ファイルで合わせておかなくてはならず、use strictとか付けると変数宣言の問題で面倒な事に。
どうしたかというと
なんとか引数に指定した変数を展開できないかなぁと思って調べていたら、evalなんてコマンドがあった。存在は知ってたけど、いまいち使いどころが分からなかったヤツ。
これを使うと実にスマートに書ける。
#!/usr/local/bin/perl # シングルクォート囲みなのでこの時点では展開されないことに注意 $tmp = q|この結果は$resultになります|; $result = 5*5; $tmp =~ s/(\$\w+)/eval($1)/eg; print $tmp.qq|\n|;この書き方のポイントは、
- $resultのような展開したい変数がいくつあっても動作すること
- requireの必要がないこと = requireを使う場合の煩雑さがない
- 展開する変数への代入を、読み込み後に行えること(requireの場合は、結果が先に分かってからrequireしないと代入されない)
- (use strict環境下で小細工しなくても普通に動く)