この記事はWindows & Microsoft技術 基礎 Advent Calendar 2015の3日目の記事です。
全然書けてない!あとでまとめなおすので…
物理構造(カーネル(HTTP.sys)とサービスとワーカープロセス)
IISが動いているWindowsが受け取ったHTTP/HTTPS要求は、HTTPカーネルモードドライバ(Http.sys)が受け取ってワーカープロセスにルーティングされます。
動作
HTTP.sysはHTTP要求ヘッダを見ますが、ルーティング先のアプリケーションがまだ登録されていない場合はWWW発行サービス(W3SVC)に問い合わせます。
W3SVCはどの要求がどのアプリケーションおよびアプリケーションプールに対応づけられているか調べます。アプリケーションをホストするワーカープロセスが起動されていなかった場合はWindowsプロセスアクティブ化サービス(WAS)を通じて起動した上で、ルーティング先の情報をHTTP.sysに渡します。
HTTP.sysは受け取ったルーティング情報を自身に登録し、アプリケーションに対応するリクエストキューを生成します。
HTTP.sysは、ルーティング先に対応するリクエストキューが一杯でなければそこに要求を入れ、ワーカープロセスに通知します(IO完了ポートが使われます)。
ワーカープロセスのIOスレッドはリクエストキューから要求を取り出して、アプリケーションが動作します。アプリケーションの動作モデルは前回の記事を見てください。
HTTP.sys余談
HTTP.sysはルーティングとリクエストキュー以外にも、カーネルモードTLSやレスポンスキャッシュ、ロギング、帯域幅制御などの機能を持っています。
ちなみにHTTP.sysはIISと密結合しているものではありません。WindowsはHTTP Server APIというWebサーバー作成用のAPIを持っていて、それを利用することで独自のアプリケーションでもHTTP.sysを利用できます。そのようにして作られたWebサーバーに、Rack(Ruby)用Webサーバー Ennouがあります。
アプリケーションプールとマルチワーカープロセス(Webガーデン機能)
アプリケーションプールに対応するワーカープロセスは、1つだけではなく複数起動して、負荷を分散させることができます。この機能をWebガーデンと呼びます。
Webガーデンでは、要求をどのワーカープロセスが処理するかは制御できません。特定の要求を特定のワーカープロセスに振り分ける、プロセスアフィニティみたいな機能は用意されていないので注意してください。
物理構造(キューとスレッドプール)
HTTP.sysのリクエストキューとアプリケーションのスレッドプールと
書くから!クリスマスまでに書くから!
非同期モデルとかの話をすこし
書くから!クリスマスまでに書くから!
さいごに
ワーカープロセスのところは結構複雑な仕組みで動いているのですが、ぶっちゃけ、ASP.NETアプリケーションのような、ワーカープロセス内でWebアプリケーションを動かすとき以外はあまり関係ない世界かもしれません。FastCGIやHttpPlatformHandlerを通じて、ワーカープロセス外のWebアプリケーションがリクエストを処置する時は、その外部プロセスの実装次第ですし、あるいは、WindowsであってもフロントWebサーバーはNginxを使いたいなどで、そもそもIISを使わないかもしれないですしね。
とはいえ、AzureのApp Serviceを使うときなど、IISの仕組みを知っておくと良いと思います。
参考リンク
- http://www.atmarkit.co.jp/ait/articles/0711/14/news137.html
- http://blogs.technet.com/b/jpiis/archive/2014/12/15/iis.aspx
- http://www.buildinsider.net/web/iis8/08
- https://fullsocrates.wordpress.com/2013/02/28/asp-net-threadstuning-thread-parameters-12-2/
- http://blogs.msdn.com/b/david.wang/archive/2006/03/14/thoughts-on-application-pools-running-out-of-threads.aspx
- http://blog.leansentry.com/all-about-iis-asp-net-request-queues/
- http://www.codeproject.com/Articles/38501/Multi-Threading-in-ASP-NET