サーバーサイドエンジニアの技術メモあれこれ

調べたことのメモがき。その他雑記もちょろちょろと。ゆるくやってます。

Apache Module メモ

※この記事は2.x系前提。概ね2.4。

What is Apache Module

www.ibm.com

可変長リストやkey-valueのハッシュテーブルなど、C言語らしからぬリッチな機能が一通りそろっておりC言語と言えど効率的に開発できる。 Apacheモジュール開発に許された特権。 メモリプールをがばっと確保して解放するということをApache側が勝手にやってくれるのでメモリ管理もかなり楽。 そしてなによりCなので高速に動作する。

メモ

おおざっぱに分かっておくとよい事

httpd起動時に準備をしている

主に認識しておくとよいのは以下。

  • confの読み込み
  • 子プロセスのfork, 設定
  • リクエスト処理ループに入る

リクエスト処理ループ

httpリクエストを受け取ったら入る処理フロー。この処理フローのどこかに到達したらモジュールが動作するように設定できる。

www.fmc-modeling.org

Apacheはモジュールの集合体である

これは忘れがちなので覚えておく

ディレクティブはモジュールの設定である

Apacheはモジュールの集合体であることを踏まえると、confはApacheに対する設定ではなくディレクティブに紐づく各モジュールに対する設定と認識する。

お手軽な作り方

CentOS系を想定

必要なrpmを入れる

yum install httpd httpd-devel

testモジュールを生成する

apxs -g -n test

MakeFile, modules.mk, mod_test.cの3つが生成される。

コンパイルする

apxs -c -i -a mod_test.c

基本的には動的リンクを用いた動的組み込みをしたほうがよいため、loadmoduleディレクティブを追加するべく -a オプションをつけてコンパイルしている。 既にLoadModuleを追加している場合は重複が発生してエラーになるようなので注意。

httpd.confにLocationを追加する

<Location "/hoge/">
    SetHandler test
</Location>

リクエストしてみる

curl "http://localhost/hoge/"

The sample page from mod_test.cと帰ってきたら成功。

自動生成したmod_test.cのコメントに書かれているとおりlynxを使っても良い

lynx -mime_header http://localhost/hoge/

mod_○○.cのざっくり全体構成

ヘッダインクルード

設定情報を保持する変数を作成する関数(ここで初期化)

設定情報を更新する関数(コマンドの配列とセットで定義)

コマンドの配列(ディレクティブで定義している設定情報を読み込むための関数や、ディレクティブの構造を指定)

フックに登録したい関数たち(フックをかけるタイミングがわかるように名前を定義するとよい)

フックに実際に登録する関数

↑で定義してきたものをディスパッチするための配列

ログ周り

ログフォーマット

httpd.apache.org

カスタムログ

httpd.apache.org

良くやるのが以下(上記リンクより引用)

LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common

LogFormatを決めてnicknameを名付ける(ここではcommon)。 CostomLogで既に定義したLogFormatを読み込み、指定したディレクトリにログファイルを生成する。 commonのところにLogFormatが展開されている感じ。

本格的に使っていくなら例えば以下のようにしてログローテートさせる。

CustomLog "|/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common env=common_env
SetEnvIf Request_URI "^/hoge$"  common_env

env=common_envのところは、CutomLogを用いてログ収集をするのかを決めるための判断軸。 右辺に指定した環境変数が存在する場合にログを落とす。 その環境変数はSetEnvIfを使って指定している。この場合、/hogeに完全一致するURIでリクエストが来ていたらcommon_env環境変数をセットするようにしてある。これによりどのリクエストのログを落とすのかの分岐が可能。

rotatelog

以下を参照。-c -L -l あたりは良く使うはず。 httpd.apache.org

参考になるモジュール

コメントもしっかり書いてあるので勉強になる。 github.com