TMCrawler

あらー、昨晩サーバーにつながらなくて更新できなかったヨ。

ってわけで、早く寝て早く起きる。起きたら、アクセスログ見て原因っぽいTMCrawlerを弾くようにした。

abでアパッチベンチマークじゃ

@IT:Apacheパフォーマンス・チューニングのポイント(2/2)

 ここからはApacheに着目して、パフォーマンス・チューニングのための準備を行う。チューニングするに当たって、まず現状を十分に分析し、具体的な目標を定めることから始めたい。目標をどれだけ具体化するかはともかくとしても、現状を数値的に知りもせずに、漠然と「遅い遅い」と騒いでいても仕方がない。

現状を数値的にとらえるにはツールが必要となる。いわゆるベンチマーク・ツールだ。Apacheには、標準で「ab」(Apache Bench)というツールが付属している。

ベンチマークじゃ!なんつって職場のapacheに負荷かけたら、かけすぎたみたいで固まった(イヤー、ちょっとやりすぎた。)

それにしても、うちのサーバー非力すぎ。blosxomにキャッシュでも導入しようかなぁ

バーチャルホストの設定状況を調べる

tracとかwiki用に新しいホスト名が欲しくてバーチャルホストを導入することにした。

apachectlだと、構文が正しいかどうかだけしかわからないが、

httpd -S

で、VirtualHostの設定状況を調べることができる。

興味ベースだけならpoundとかも触ってみたい気もするが。

dynamic_cacheプラグインで静的なキャッシュを

うちのマシンは非力でcgiの起動は結構負荷がかかるので、以前からどうにかしたいなぁと思っていた。いま使っているdynamic_cacheプラグインで、負荷軽減はかなりされたんだが、それでも最初にcgiを起動してしまうので、どうにかして静的なキャッシュの仕組みを作れないかと四苦八苦してみた。

現在、サーバーの設定は.htaccessでファイルとかディレクトリがない場合に、blosxom.cgiを実行するようになっている。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ blosxom.cgi/$1 [L,QSA]

だから、blosxomのディレクトリとdynamic_cacheのキャッシュ先を一緒にすれば、キャッシュされたファイルは次回からは直接httpdにより処理される。

ここまでは以前試してあったのだが、これだと問題が3つある。一つは設定に関することで、残りの二つはプラグインをいじらないといけない問題だ。

  1. rootのindex.htmlとblosxom.cgiがバッティングしてえらいことになる。
  2. dynamic_cacheはヘッダーも含めてキャッシュするので、キャッシュ表示の際にContent-Typesとか表示されてしまう。
  3. recache=allでキャッシュディレクトリ以下のすべてのファイルが消去されてしまうため、キャッシュ先をルートに設定するとblosxomのサブディレクトリ以外の画像ファイルとかも消してしまう。

1に関しては先日発見した通りに適当なディレクトリを用意してそこにRewriteするようにすればよい。うちだとこんな感じ。

DirectoryIndex index.html
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule   ^([^.].*)$        .bldir/blosxom.cgi/$1 [L,QSA]

で、残りの二つはdynamic_cacheプラグインを修正して対応。2はヘッダー除いて保存するようにdynamic_cacheを書き換えた。

    # キャッシュファイル出力
    if ($fh->open("> $cache_dir/$cachefile")) {
            $blosxom::output =~ s/^Content-Type: .*?; charset=.*?\r?\n\r?\n//;
            print $fh $blosxom::output;
            close $fh;
            logput("SAVE ");
    }

3に関しては、dynamic_cacheで使っているFile::Pathって知らなかった。
ドキュメント読んだら、消したいディレクトリとかファイルのリストのリファレンスを与えればよいらしい。
dynamic_cacheだとキャッシュ用ディレクトリを消すようになっていたので、ここを書き換えた。

    # キャッシュ全クリア
    # 【flavourの記述例】<input type="hidden" name="recache" value="all">
    if($recache=~/all/i){
        require File::Path;
        my @del_dir = map {$cache_dir . "/" .$_} ("Computer", "Etc", "daily", "Food",
                                                  "trekking", "index.rss10", "index.html",
                                                  "2004", "2005", "2006",
                                                  "index.rss", "index.xml");
        File::Path::rmtree(\@del_dir) and logput("CLEAR","ALL");
    }

こんな感じで、今のところ静的にキャッシュされている感じだが、このせいで、taggingプラグインみたいにgetで処理するプラグインが動かなくなってしまった。

これもRewriteRuleでうまく処理できるのだろうか?

Search::Estraierを使うことを考えたほうがよいかなと思ったりもしてるが。

URLからblosxom.cgiをどうやったか隠せますか?

長年の悩みをついに解決(表題)

僕はmod_rewriteを使わずに直接httpd.confを編集して「この余計な文字列」を置き換えようとしていたノダ。要は、毎度毎度.htaccess読むのはパフォーマンスが落ちるんじゃねーの?みたいな些細なことをうっかり気にしたわけ(細かいことにこだわってしまった)。

で、ScriptAliasを指定してみたり、ディレクティブにIndexとして指定してみたり、デフォルトのインデックスに追加してみたりといろいろやったが、どうも.cgi以降の/がうまく解釈されない。(Computer/blosxom/index.html みたいのがきちんと表示されない。)

今考えると、それはそうかもというかそうなのかナァとは思うんだけどなぜだか出来ない理由はわからず終い。というわけで、結局mod_rewriteに頼ることになったんだが、以下のエラーがerorr.logに。

[error] mod_rewrite: maximum number of internal redirects reached. Assuming configuration error. Use 'RewriteOptions MaxRedirects' to increase the limit if neccessary.

調べてみると、無限ループらしい。よくよく調べてみると、.htaccessでもhttpd.confでもエイリアスを切ってたのでそのせいっぽい。httpd.confのほうは、チャレンジした残骸。気をつけよう。

あと、気をつけるのはAllowOverrideを"All"にすること。参考にしたのは下のサイト。

Apache+WebDAVインストール(1)

WebDAVをFTPの代わりに使うといいことは色々あります

  • HTTPポートを空けておけば、会社とファイルのやり取りが出来るので、多少サイズが大きくなっても、物理的な媒体にたよらなくてイイ
  • 余計なポートをあけなくていい。(家サーバーにFTPポートをあけるのはちょっと躊躇するヨネ)
  • Windows2000だとネットワークフォルダとして見えるのでドラッグドロップでファイル操作が可能
  • subversionでバージョン管理も可能(家では必要ないけど)
  • 仲間内での共有フォルダとして使うことも可能

家イントラとか会社イントラだとSambaでも良いんだけど、大体会社だと普通は外向けにそんなポート番号開いて無いでしょ?かといって、ftpも申請する必要があったりするわけで(色々と)面倒くさい。そこで、WebDAVを使うとこれらのファイル転送の問題がバシッと解決されるわけです。

あとはセキュリティーの設定がapacheの設定を使えるのが嬉しい。もしもapache運用したことがあれば、セキュリティーの設定をゼロから覚える必要がないし、ログ管理も楽なのダ。

まずはapacheのインストール。WebDAVを使うためにはapxsが必要なのでdevもあわせてインストールします。後ろの二つは特に必要ないと思うけど、まぁ入れておく。

# rpm -Uvh httpd-2.0.47-10
# rpm -Uvh httpd-devel-2.0.47-10
# rpm -Uvh httpd-manual-2.0.47-10
# rpm -Uvh redhat-config-httpd-1.1.0-5

外向けに使う場合は、常に最新版をインストールするベシ。最初は自動アップデートとか気になって触ったりしたんだけど???な挙動が多いので、地道にダウンロードしてrpmからインストする従来の方法に戻っています。Fedora Projectから最寄のFTPサーバー探して、最新版を落とします(httpd-2.0.50-1.0とhttpd-devel-2.0.50-1.0)

# rpm -Uvh httpd-2.0.50-1.0
# rpm -Uvh httpd-devel-2.0.50-1.0
# rpm -qa | grep httpd #確認
httpd-2.0.50-1.0
httpd-devel-2.0.50-1.0

/etc/httpd/conf/httpd.confを設定。ServerAdminとServerNameを指定すればとりあえず動くはず

# # ServerAdmin: Your address, where problems with the server should be
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. admin@your-domain.com
#
ServerAdmin Your@E.mail.address

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If this is not set to valid DNS name for your host, server-generated
# redirections will not work. See also the UseCanonicalName directive.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
# You will have to access it by its address anyway, and this will make
# redirections work in a sensible way.
#
ServerName Your.server.Name

確認はapachectl -tでOKがでればOK。なんか色々いわれたら、素直になおすベシ。

# apachectl -t
Syntax OK

ランレベルの確認したら起動。restartするのは僕の癖。普通にstartでもイイ

# /sbin/chkconfig --level 35 httpd on
# /sbin/chkconfig --list httpd
httpd 0:オフ 1:オフ 2:オフ 3:オン 4:オフ 5:オン 6:オフ
#/sbin/service httpd restart

Apache+WebDAVインストール(2)

Apache2でWebDAV使いたければhttpd.confに以下のモジュールがロードされるようになっているか確認すればよい

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so

あとはhttpd.confにWebDAV用の記述を追加すればよいのだが、これだと、日本語が化けるし、一度バケルと消すのが面倒になる。そもそも今回WebDAV導入の目的の一つが「会社-家間での快適なファイル移動」なので、日本語はちゃんと扱えないとダメデショウということで、mod_encodingを導入(自然な流れともイエル)。

WebDAV Resources JPから、Apache 2.0用のmod_encoding-20020611a.tar.gzとmod_encoding.c.apache2.20040616をダウンロード

# tar xvfz mod_encoding-20020611a.tar.gz
# cd mod_encoding-20020611a/lib
# ./configure
# make
# make install #suで
# cd ..

でもって、mod_encoding.c.apache2.20040616をmod_encoding.cとして上書きしたら

# ./configure --with-apxs=/usr/sbin/apxs
# gcc -shared -o mod_encoding.so mod_encoding.o -Wc,-Wall -L/usr/local/lib -Llib -liconv_hook
# mv mod_encoding.so /etc/httpd/modules/mod_encoding.so #su

下のようになるかチェック

# ldd mod_encoding.so
libiconv_hook.so.1 => /usr/local/lib/libiconv_hook.so.1 (0x00373000)
libc.so.6 => /lib/libc.so.6 (0x00a6c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00a57000)

おかしい場合は/etc/ld.so.confに/usr/local/libを追加して

# ldconfig

ここまで終わったら、httpd.confにdav用の設定を追加

#モジュール追加
LoadModule encoding_module modules/mod_encoding.so

Alias /mydav "/usr/local/dav"

<IfModule mod_encoding.c>
EncodingEngine on
NormalizeUsername on
SetServerEncoding UTF-8
DefaultClientEncoding JA-AUTO-SJIS-MS SJIS
</IfModule>

# DAVアクセスされるディレクトリの設定
<Location "/mydav">
DAV On
AuthType Basic
AuthName "WebDAV Folder"
AuthUserFile "/usr/local/passwd/davpwd"
AuthGroupFile "/dev/null"
Require valid-user
Options Indexes
</Location>

認証を入れるとこんな感じになります。後は構文チェックしてOKでたら再起動

# apachectl -t
Syntax OK
# /sbin/service httpd reastart

モジュールをロードしないとSyntax OKが出ても動きません。いくつかDAVサーバーを設定しているんだけど、一度そのおとぼけミスで30分ほどハマッタことがあるヨ。

webalizerの文字化け対策とサーチエンジンリファラのグループ化

Webalizerで以下の点を対応することに

  • 検索エンジンのクエリを収集するために、いくつかのサーチエンジン追加
  • そのための文字コードをutf-8に統一するためのスクリプト導入
  • リファラが検索エンジンで埋もれないようにグルーピング
  • cronに処理を追加

/etc/webalizer.confに日本のサーチエンジンと検索語を追加

SearchEngine google.co.jp q= SearchEngine search.msn.co.jp q= SearchEngine sf.livedoor.com q= SearchEngine search.yahoo.co.jp p= SearchEngine yahoo.co.jp p= SearchEngine search.biglobe.ne.jp q= SearchEngine infoseek.co.jp qt= SearchEngine search.nifty.com Text= SearchEngine goo.ne.jp MT= SearchEngine excite.co.jp search=

続いて、/etc/webalizer.confにリファラをグルーピングして、表示するように設定を追加する

GroupReferrer .google. Google GroupReferrer .104/search Google HideReferrer .google. HideReferrer .104/search GroupReferrer search.yahoo.co.jp Yahoo!Japan GroupReferrer srd.yahoo.co.jp Yahoo!Japan HideReferrer search.yahoo.co.jp GroupReferrer search.goo.ne.jp goo HideReferrer search.goo.ne.jp GroupReferrer search.biglobe.ne.jp biglobe HideReferrer search.biglobe.ne.jp GroupReferrer search.msn MSN HideReferrer search.msn GroupReferrer excite.co.jp/search.gw excite HideReferrer excite.co.jp/search.gw GroupReferrer infoseek.co.jp infoseek HideReferrer infoseek.co.jp

文字コードの変換は、flatray.comからスクリプトをもらってきてカスタマイズして使用しました。

変更した部分は以下の部分。変更したファイルはコレです。

  • スクリプト中に、インプット、アウトプットファイルを記述
  • utf8で出力するように変えた

わかりやすいように、logdecodeという名前で適当なディレクトリに保存して、クローン対応。そして、こいつで変換したログを見に行くように/etc/webalizer.confを書き換えしておく。

#LogFile /var/log/httpd/access_log LogFile /var/log/httpd/webalizer_log

デコードしてからwebalizerが動くようにするため、/etc/cron.daily/00webalizerを編集

#! /bin/bash # update access statistics for the web site #if [ -s /var/log/httpd/access_log ] ; then # /usr/bin/webalizer #fi if [ -s /var/log/httpd/access_log ] ; then /usr/local/bin/logdecode;/usr/bin/webalizer fi exit 0

これで、Webalizerの結果がかなりみやすくなったヨ。

Infoseek SideWinder/2.0R 大暴れの巻

朝から、軽く思いついたプログラムを書いとこうとサーバーにアクセスしてみると、激重なので調べてみると、昨日まで利口に2時間おきにindex.rss10をGETしていたInfoseek SideWinder/2.0Rが、深夜から豹変シテマス。

というわけで、朝のプログラミング(朝プロ)どころではないぞ。

00:27過ぎから数秒おきに1800回ぐらいアクセスしてんですけど?

blosxomだとそのたびにCGIが動くので、負荷がものすごいんですけども?

アクセス禁止にしたらあきらめてお帰りになってくれるかと期待したんですが403でも果敢に攻めてくるんですけど?

ちゅうわけで、無駄にログばかり溜まってコマル。

210.148.XXX.XXX - - [02/Jun/2005:08:04:37 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:39 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:39 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:49 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:50 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:50 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:51 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:56 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:04:56 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)" 210.148.XXX.XXX - - [02/Jun/2005:08:05:00 +0900] "GET / HTTP/1.0" 403 3931 "-" "Infoseek SideWinder/2.0R (Linux 2.6.6-1.381smp i686)"

整然と並んだforbiddenのログもまたをかし(なわけないな)。

Apacheのワームログ分離

最近、wormまわりのログが凄くて、気持ち悪いので、イントラからのアクセスを記録しないで、wormログを別のファイルに書き出すようにした。

要するに、SetEnvIfでフラグ付けていって、ログにはフラグごとに記録すればいい。