はじめに
ASP.NET CoreをIISで動かしたときに、Httpリクエストがどういう流れでアプリケーションコードまで到達するのか気になり調べてみました。
前提
IISのバージョンによってアーキテクチャが異なります。
IIS 7.0以降について調べた内容となります。※私の手元の環境はIIS 10.0となります
ホスティングモデルはASP.NET Core 3.0以降ではデフォルトの「インプロセスホスティング」となります。
- IIS 7.0以降
- ASP.NET Core
- インプロセスホスティング
IISのアーキテクチャ
IISの構成要素
IISの構成要素は、このサイトより引用
- HTTP プロトコルスタック (HTTP.sys) HTTP.sys は、端的に言うと HTTP/HTTPS 用の通信ドライバです。HTTP コネクションの管理、HTTP ヘッダー解析、URL/URI/IRI の解析、HTTP リクエストのログ機能、キャッシュ機能、および、SSL 機能等、多くの機能が HTTP.sys に搭載されています。
- Windows プロセスアクティブ化サービス (Windows Process Activation Service : WAS) WAS は、ワーカープロセスを管理するサービスです。実行中のワーカープロセスの健常性を監視しています。また、WASは、構成情報の読み取りなども行います。
- World Wide Web 発行サービス (World Wide Web Publishing Service : W3SVC) W3SVCは、HTTP.sys 及び WAS と通信を行い、HTTP.sys に構成情報を提供します。また、W3SVC は、Web サイトのパフォーマンス監視も行います。
- 構成ストア 構成ストアは、XML 形式の設定ファイル群を表す仮想的なストアです。IIS 全体の構成情報は、 IIS のサーバーレベルの構成ファイルである、applicationHost.config に格納されています。この中には IIS の構成が含まれます。また、アプリケーションの構成は、ご存じの通り、各アプリケーションの web.config に含まれています。
- ワーカープロセス ワーカープロセスは、要求の処理と応答の生成を行うプロセスです。
ASP.NET CoreのWebアプリケーションはワーカプロセスで実行されます。
Httpリクエストの処理フロー
IISがHttpリクエストを処理する流れは、下記となります。
さきほどのサイトを参考に書きました。

- HTTP要求がクライアントブラウザからサーバーへ到着します。HTTP.sys が要求を受け取ります。要求が応答キャッシュのエントリに一致した場合、HTTP.sys はキャッシュ応答をカーネル モードから直接送信します。(上図の赤ライン)
- HTTP.sys が要求の送信先アプリケーションの構成情報が登録されているか確認をし、登録されていなかった場合は、HTTP.sys は W3SVC に問い合わせを行います。
- W3SVC は、WAS へ要求を渡します。(以降、上図の黄色ライン)
- WASは、IIS のサーバーレベルの構成情報である、applicationHost.config を構成ストアから取得します。
- WASは、要求されたアプリケーションプール内のワーカープロセスを確認します。ワーカープロセスが存在しない場合は、そのアプリケーションプール用のワーカープロセスを起動します。
- WASより、アプリケーションプールの情報や構成情報を W3SVC に渡します。
- W3SVC は、WASから受け取った構成情報に基づき、HTTP.sys へ設定および更新の通知をします。
- HTTP.sysは、その通知を基に、アプリケーション用のキューを作成してから、適切なワーカープロセスに要求を転送します。
- 要求を受け取ったワーカープロセスは、要求処理を開始します。
- 要求処理パイプラインのそれぞれの処理を行い、ワーカープロセスは、要求の処理結果を HTTP.sys へ返します。
- HTTP.sys がクライアントに応答を送信します。
動作確認
環境
- Windows Server 2019 試用版
- IIS 10.0
- Hyper-V 10.0
リスナーの確認
IISを立ち上げると、
ファイアウォールの受信規則にTCP:80番ポートの許可が追加されます。

コマンドプロンプトでnetstat -anoを実行するとTCP:80番ポートで待ち受けていることが分かります。
C:\Users\Administrator>netstat -ano
プロトコル ローカル アドレス 外部アドレス 状態 PID
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP [::]:80 [::]:0 LISTENING 4
プロセス/サービスの確認
カーネルモード
TCP:80番ポートで待ち受けているPID4のプロセスをタスクマネージャーで確認するとWindowsカーネルC:\Windows\System32\ntoskrnl.exeだと分かります。

さらに、ProcessExplorerでPID4のプロセスを見ると下記を呼び出してることが分かります。

- Interrupts(Hardware Interrupts and DPCs)
- smss.exe(Windows セッション マネージャー)
C:\Windows\System32\smss.exe
おそらくですが、InterruptsからTCPIP.sysC:\Windows\System32\drivers\tcpip.sys経由でHTTP.sysC:\Windows\System32\drivers\http.sysが呼び出される?!のではないかと思ってます。
ユーザーモード
タスクマネージャーのサービスを見ると、W3SVC, WASがあり、PID868で実行されていることが分かります。

コマンドプロンプトでも確認ができ、tasklist /svcを実行するとW3SVC, WASがホストされているsvchost.exeC:\Windows\System32\svchost.exe、PIDが分かります。
C:\Users\Administrator>tasklist /svc
イメージ名 PID サービス
========================= ======== ============================================
svchost.exe 868 W3SVC, WAS
注意として、このサイトより引用
svchost.exe というプロセスは Windows で各種サービスをホストするための汎用プロセスです。 従って svchost.exe という名前でホストされているサービスは多数ありますので、svchost.exe というプロセスが見えたからと言って、 IIS ではありませんので注意してください。
Httpリクエストを投げて、
ProcessExplorerでPID868のsvchost.exeを見るとワーカプロセス(w3wp.exec:\Windows\System32\inetsrv\w3wp.exe)を呼び出してることが分かります。

タスクマネージャーでPID4976のw3wp.exeを見ると、

IISのアプリケーションプール名と一致します。

ワーカプロセスは、ブラウザを閉じても(TCPのコネクションが切れても)実行し続けます。
ワーカプロセスは、アプリケーションプールの設定にしたがい(デフォルトでは20分で)終了します。

イベントログWindowsログ/システムを見るとWASがワーカプロセスを終了させたことが分かります。

結果
IISの構成要素が動作していることが分かりました。
参考サイト
- IISについて
- ASP.NET Coreモジュールについて
- ホスティングモデルについて
- IIS と ASP.NET Core を使用したインプロセス ホスティング|Microsoft Learn
- IIS と ASP.NET Core を使用したアウトプロセス ホスティング|Microsoft Learn
- ASP.NET Core Hosting Mechanisms. Understanding what options are…|by Dhananjeyan Balaretnaraja|Medium
- Hosting ASP.NET Core Applications on IIS – A Detailed Look|Code Wala
- ASP.NET Core In Process Hosting on IIS with ASP.NET Core - Rick Strahl’s Web Log
- モジュールについて