[Warning]
より効率のよい同時接続数制限モジュールができたので、上記のページを参考にして下さい。
[/Warning]
[note]
- mod_vlimitconn.c [Download]
- 関連記事
[/note]
またapacheモジュールを作ってみた。
今回は、IP単位やファイル単位で同時接続数制限を実現するapacheモジュールであるmod_limitipconnを作り替えた。
ほぼ丸々書き換えなので、patchにしても意味なかった。
まずは、mod_limitipconnの下記問題点を改善した。
- VirtualHostに対応していない
- シンボリックリンクを含むドキュメントルートに対応していない
- 二つのVirtualHostのドキュメントルートが同じディレクトリにリンクを張っていた場合、高負荷をかけるCGIが存在した場合、二つのVirtualHostで共通することになるが本当のリアルパスで制限できず、ドメイン毎に制限かけなくてはならない。
- ドメインエイリアスなどをとった場合に、システム的に契約ドメインのドキュメントルートにドメインエイリアス用のリンクをはる場合などがあるため、契約ドメイン単位で制限をしたい。
- 不要な機能が多い(OnlyIPLimit、NoIPLimitなどのMIMEタイプの制限)
- 殆どの場合、Files・FilesMatch・Directory・DirectoryMatchなどで対応できる。
改善による機能としては、
- VirtualHostに対するIP単位での同時接続数制限
- VirtualHostに対する同時接続数制限(VirtualHostのMaxClients)
- 引数にリアルパスを指定することにより、シンボリックリンクを含むドキュメントルートにも対応
- 不要な機能を削除し、シンプルな設定を実現
- .htaccess対応
- error_logに出すと顧客に制限がばれちゃうので、システム管理者が見れるところにログ出力
である。
VirtualHostに対する同時接続数制限
VirtualHostの設定の中に、下記設定を記述することで、VirtulHostに対する同時接続数制限ができる。
- VirtualHostのMaxClientsを50に設定する場合
VlimitConnVhost 50
- VirtualHostへの同一IPからの同時接続数を10に制限する場合
VlimitConnIP 10
シンボリックリンクを含むドキュメントルートにも対応
例えば、あるドメインでVirtualHostを契約し、ドメインエイリアスで契約したVirtualHostと同じドキュメントルートに対して、シンボリックリンクでドキュメントルートを設定したとする。
そして、契約ドメインで高負荷をかけるCGIが存在した場合、契約ドメインでなけでなくドメインエイリアスでのドメインからアクセスした場合も高負荷をかけるCGIにアクセスできる。
そのため、制限をかける場合は両方のドメインからのアクセスに制限を有効にできないといけない。
apache的には、アクセスのあったパスをシンボリックリンクからリアルパスへと変換してくれないので、Directiveを使って制限しようと思うと両方のドメインを記述しなくてはならない。
例えば、契約ドメインがhoge.com、ドメインエイリアスがhoge1.com・hoge2.comだったとすると、warui.cgiをmod_limitipconnで制限したい場合、
<Files /docroot/hoge.com/warui.cgi>
MaxConnPerIP 3
</Files>
<Files /docroot/hoge1.com/warui.cgi>
MaxConnPerIP 3
</Files>
<Files /docroot/hoge2.com/warui.cgi>
MaxConnPerIP 3
</Files>
としなければならない。
ドメインエイリアスが10個あったら10個設定を各必要がある。
なので、ファイルシステム的なリアルパスに対して制限をかけられるように改善した。
mod_vlimitconnでは以下のように設定する。
VlimitConnIP 2 /docroot/hoge.com/warui.cgi
これで、シンボリックリンク経由のアクセスもmod_vlimitconn内部で解析し、リアルパスが第2引数とマッチした場合はリアルパスへの同一IPからの同時接続数を2に制限する。
VlimitConnVhost 5 /docroot/hoge.com/warui.cgi
上記の記述だと、VirtualHostに設定した場合は、VirtualHost全体への同時接続数も含めて、第2引数のファイルへ5クライアントしか同時に接続できない設定となる。
これは、mod_limitipconnの問題と一緒で、ファイル単位ではなく、ファイル以外にアクセスがあった場合もその値をカウントしてしまう。
このあたりは、プロセス間通信を用いてカウンターをファイル単位で保持するなどの実装が必要で、今回はmod_statusを用いた実装のままにしている。
不要な機能を削除し、シンプルな設定を実現
基本は、「VlimitConnIP」と「VlimitConnVhost」のみとした。
.htaccess対応
あるディレクトリ以下に同一IPからの同時接続数を3に制限したい場合は、confに書くと、
<Directory /docroot/douga_dir>
VlimitConnIP 3
</Directory>
VlimitConnIP 3
システム管理者のみが見れるところにログ出力
error_logにモジュールのログを出すと、大概の場合は顧客がerror_logをみれるようにしてると思うので、見れないような場所にログをだすようにした。
また、ログ出力フラグファイルをtouchすることで、ログを出力するようにしている。
- ログ出力フラグファイル
/var/log/apache/VLIMITCONN_LOG
- ログ出力ファイル
/var/log/apache/mod_vlimitconn.log
- デバッグログ出力フラグ(syslogにデバッグログを出力)
/var/log/apache/VLIMITCONN_DEBUG
ファイル名変更等は、ソース内の以下の実装を変更する。
#define VLIMITCONN_LOG_FILE "/var/log/apache/mod_vlimitconn.log"
#define VLIMITCONN_LOG_FLAG_FILE "/var/log/apache/VLIMITCONN_LOG"
#define VLIMITCONN_DEBUG_FLAG_FILE "/var/log/apache/VLIMITCONN_DEBUG"