Lighttpd+mod_cmlを考えてみました
ダイナミックコンテンツをうまく利用するためのモジュールとしてmod_cmlというものがあります。mongrelで紹介されていたのが気になって調べてみることにしました。
一口にキャッシュといってもその有り様はアプリケーションにより千差万別、様々な場面が想定されるわけLighty+mod_cmlではその多様性を組込型言語luaを使ってプログラミングします。
Lighttpdのmod_cmlを使用するにはまず、luaとlibmemcacheをインストールして--memchacheと--luaオプションを付加してLightyをリメイクします。
tar zxvf lua-5.1.1.tar.gz cd lua-5.1.1 make linux make linux install tar jxvf libmemcache-1.4.0.rc2.tar.bz2 cd libmemcache-1.4.0.rc2 ./configure make make install export LUA_CFLAGS='-I/usr/local/include' export LUA_LIBS=/usr/local/lib/liblua.a ./configure --with-memcache --with-lua chcon -c -v -R -u system_u -r object_r -t textrel_shlib_t \ /usr/local/lib/mod_cml.so
これで、準備完了(chcon ~ ... はSELinuxの設定)。lighttpdのコンフィグレーションはたった一行。これですべてのリクエストの前にpower-magnet.cmlが実行されます。
cml.power-magnet = "/path/to/rubricks/config/power-magnet.cml"
この、power-magnet.cmlにluaでアプリケーション固有のキャッシュ処理を記述します。Railsにはそもそもキャッシュ機能がありますのでアプリケーション側では特別な処理は必要ありません。後は、power-magnet.cmlにコードを記述するわけですがluaを使ってプログラミングするといってもゼロから書き始めるわけではなく、mod_cmlにはすでにいくつかの変数・関数が定義されていますのでこれを使用します。
- request["REQUEST_URI"]
- request["SCRIPT_NAME"]
- request["SCRIPT_FILENAME"]
- request["DOCUMENT_ROOT"]
- request["PATH_INFO"]
- request["CWD"]
- request["BASEURI"]
- get["パラメータ名"]
- string md5(string)
- number file_mtime(string)
- number file_isreg(string)
- number file_isdir(string)
- number dir_files(string)
- string memcache_get_string(string)
- number memcache_get_long(string)
- boolean memcache_exists(string)
変数も関数も名前でなんとか意味はわかります。file_isreg()だけはわからなかったのですがソースをみたらstat(...) S_ISREG(st.st_mode)でしたの単にレギュラーファイルか否かをチェックしているだけです。「..」は文字連結連結。
これらを踏まえてMongrel: Lighttpdの例をみると最初のブロックでは、いわゆる「ただいまメンテナンス中です...」のファイルがあったら即それを表示。以降の処理でURIをチェックしてファイル名を作成し、そのファイルがfile_isregであれば、output_includeにそのファイル名を挿入します。mod_cmlでは戻り値が0(CACHE_HIT)であればoutput_includeからファイルを読み込みそれを出力する仕掛けです。コンテントタイプを指定する場合はoutput_contenttype="text/html"のように設定します。
dr = request["DOCUMENT_ROOT"]
if file_isreg(dr .. "/maintainance.html") then
output_include = { dr .. "/maintainance.html" }
return CACHE_HIT
end
f = request["REQUEST_URI"]
if f "/" or f "" then
file = dr .. "index.html"
elseif not string.find(f, "%.") then
file = dr .. f .. ".html"
else
file = dr .. f
end
if file_isreg(file) then
output_include = { file }
return CACHE_HIT
end
return CACHE_MISS
|
ここまで調べてみて、んんん~mod_rewriteや条件構文でもいいんじゃないかなっていう気がしてきました。まあ、お勉強したということで。










Comments