この記事はWindows & Microsoft技術 基礎 Advent Calendar 2015の2日目の記事です。
IISの実装モデルは2015年Webサーバアーキテクチャ序論に挙げられている中からひとつ選ぶとすればマルチスレッドモデルになりますが、ワーカープロセスによるマルチプロセスも組み合わさっているので、ハイブリッドアーキテクチャとしてもよいかと思います。
プロセスとスレッドの細かい話は明日の後編のほうで扱おうかと思います。今日は概念的なところだけ。
なお、この記事は基本的に(Windows Server 2008の)IIS 7.0から(Windows Server 2012 R2の)IIS 8.5までを想定して書いています。
論理構造(Webサイトとアプリケーションとアプリケーションプール)
WindowsにインストールできるIISは1つだけです。ですが、1つのIISは複数のWebサイトを管理できます。
IISにおけるWebサイトとは、大まかにいうとIPアドレスとポートとホスト名(FQDN)の組み合わせと対応付けられる単位です。IISをインストールすると「Default Web Site」という名前のWebサイトが1つ自動的に設定されます。これは「このマシンのすべてのIPアドレス」「80番ポート」「任意のホスト名」の組に対応づけられています(後で変更できます)。
1つのWebサイトは、1つ以上のアプリケーションを含みます。
IISにおけるアプリケーションとは、Webサイト内の特定ディレクトリ以下に対するHTTP要求を処理する単位です。Webサイトのルートディレクトリはアプリケーションとして構成されるので、1つのWebサイトは1つ以上のアプリケーションを含んでいることになります。
1つのアプリケーションは、どれか1つのアプリケーションプールに対応付けられます。
IISにおけるアプリケーションプールとは、アプリケーションをホストするワーカープロセスの論理的なグループです。アプリケーションプールとワーカープロセスの関係は、一言でいえば「アプリケーションプールはワーカープロセスのひな型」です。ワーカープロセスは、アプリケーションプールの設定に従って生成されたり破棄されたりします。細かい話は明日の後編のほうで扱う予定です。
論理構造(アプリケーションとHTTPモジュールとHTTPハンドラー)
ざっくりイメージを書くとこんな感じ。
要求を実際に処理して応答を作るのはHTTPハンドラーが担当します。どの要求をどのハンドラーが担当するかはURLのパスや拡張子などをもとにのマッピングします。
HTTPハンドラーが処理をする前後に共通的な追加処理を行うのがHTTPモジュールです。
「あれ?IISってISAPIフィルターとISAPI拡張が動くんじゃなかったっけ?」とお思いの方へ。その動作はIIS6以前のモデルです。現在のIISでは「クラシックモード」と呼ばれていますがデフォルトの動作モデルではありません。デフォルトは、ここで書いている「統合モード」というものに変わっています。
統合モードでは、HTTPハンドラーもHTTPモジュールも、ネイティブ(C++で実装する)とマネージド(.NET言語で実装する)を混在させることができます(厳密には、ネイティブの場合はHTTPハンドラーもHTTPモジュールとして実装します。)
統合モードをもう少し細かく書くとこんな感じ。
IISのアプリケーションにはHTTP要求を処理するパイプラインが定義されています。グレーの箱については上から順にイベントが発火します。で、イベントハンドラを登録しているHTTPモジュールがコールバックされ、それぞれの処理を行います。ハンドラー呼び出しのところは、マネージドHTTPハンドラーについては、選択されたHTTPハンドラーが普通に呼び出されます。ネイティブHTTPハンドラーについては、実際にはHTTPモジュールとして実装されますので、イベント発火⇒コールバックの流れになりますが、登録されているモジュールの中でHTTPハンドラーとして選択されたモジュールだけがコールバックされる感じです。
HTTPモジュールやHTTPハンドラーは、HTTP要求とHTTP応答を抽象化したオブジェクトであるHTTPコンテキストというものにアクセスして、それを操作できます。ただし、実際にHTTP応答を送信するのはパイプラインの最後に達した時になります。
いろいろなHTTPハンドラー
注:ここに書いてるHTTPハンドラーは、ネイティブ実装のものが多いです。そして、ネイティブのHTTPハンドラーは、実際にはHTTPモジュールとして実装されます。あしからず。
ざっくり書くと、IISのワーカープロセス内で全てを処理する(インプロセス)ものと、外部のプロセスで処理するもの(アウトプロセス)の2つに分けられます。
インプロセス
- 静的ファイルハンドラー
- ASP.NETのハンドラー
- Web FormsとかMVCとか
- ASP.NET 5では使わない
アウトプロセス
- CGIハンドラー
- 要求が来るたびにプロセスを起動する形。もう誰も使わんだろ……
- FastCGIハンドラー
- IISでPHPをホストするときの公式なやつ
- 昔はクラシックモードのISAPI拡張でPHPをインプロセス処理するという、Apacheのmod_phpっぽいものがあったがオワコン。IISのインプロセス、それはすなわちマルチスレッド。スレッドセーフPHPの闇
- HttpPlatformHandler
- HTTPプロトコルでプロセス間通信
- 外部サーバープロセス起動+簡易リバースプロキシ(ラウンドロビン)
- その他さまざまな言語のアプリを動かすなら今はこれ
- 2015年になってはじめて正式リリース(なぜこれまでなかったのか……慢心、環境の違い)