2025.07.16

#27 DynatraceによるIIS処理遅延の原因分析

目次

開く

     

    はじめに

    Microsoft IISは、Windows標準のWebサーバーです。GUIで簡単に設定・操作が可能で、多くのWebシステムに採用されています。弊社でもIISの性能管理に関する多数のご要望をいただいており、そのほとんどが業務に欠かせない重要なWebシステムです。そんなIISですが、セッション管理に関するパフォーマンスの注意点をご存じでしょうか。

     

    本記事では、IISのセッション管理の仕様が原因となり、深刻なレスポンス遅延が発生した事例をご紹介します。こちらの事例では、たった1ユーザーのネットワーク品質の問題で、IISのセッション管理の負荷が増大し、Webシステムのレスポンスが通常の20倍遅延するという事態となりました。IISの仕様が改善されない限り、他のWebシステムでも同様の問題が発生する可能性があります。対策も記載しましたので、IISで構築されたWebシステムを開発・保守されている方は、ぜひご一読ください。

     

    また、今回のレスポンス遅延はDynatraceにより分析しました。IISのWebサーバーにOneAgentを導入されている環境でしたら、現時点でIISのセッション管理の負荷がどの程度なのかすぐに確認可能です。該当の環境がある場合は、ぜひ確認してみてください。

     

    *文中、斜体になっている単語はDynatrace画面上/ドキュメント内で使用される用語となります
     例)ServiceHost など
    *青色の色掛部分は操作対象のボタンを表しています
     

    事象の概要

    Webシステムで処理遅延が発生したお客様より、Dynatraceによる原因分析をご依頼いただきました。ある時間帯以から突然システム全体で処理が遅くなり、IISの再起動によって一時的に復旧したとのことです。

     

     システム構成

    • Web/APサーバー Windows 2019 + IIS 10 + ASP.NET 4.8 (Azure Virtual Machine)
    • DBサーバー Azure Database for PostgreSQL フレキシブルサーバー

     

    お客様が確認された内容

    • サーバー負荷:通常日と比較して特別にCPU、メモリの使用量が高いわけではない
    • 環境変更:1ヶ月前に下記の変更を行って以降、新たな変更はなかった
      • バッチ改修(Webアプリは修正なし)
      • サーバーのスペックアップ
      • ウイルスソフトのアップデート

     

    このように、お客様にて確認した範囲では原因が特定できなかったため、原因調査と次回発生時の早期検知方法の確立が求められました。

     

     

    Dynatraceによる原因分析

    事象発生時、Dynatraceでは「User action duration degradation」という処理遅延のプロブレムが検出されていました。

     

     

    図1:Problem画面
    図1:Problem画面

    図1:Problem画面

     

     

    プロブレムの詳細を確認すると、通常は平均2.5秒程度のWebシステムのレスポンスが、1分と20倍以上に遅延し、それが1時間も継続していました。また、「根本原因」のセクションには以下のイベントが検出されていました。

     

    1. 1.    処理遅延を示す「Service response time degradation
      2.    エラーの発生を示す「Service failure rate increase

     

     

    図 2:Problemの詳細
    図 2:Problemの詳細

    図 2:Problemの詳細

     

     

    [応答時間の劣化を分析]をクリックすると、下図のように応答時間の内訳が表示されます。今回の事象では、IIS modulesの応答時間が長く、特に「Session」モジュールの応答時間が長い状況でした。

     

     

    図 3: 応答時間の劣化を分析
    図 3: 応答時間の劣化を分析

    図 3: 応答時間の劣化を分析

     

     

    [失敗率の劣化の分析]ボタンをクリックすると、下図のようにエラーメッセージや、エラーが発生しているリクエストのURLが表示されます。今回の事象では、HTTP 500Internal Server Error)が出力され、「The request queue limit of the session is exceeded.」というメッセージが出力されていました。

     

     

    図 4: 失敗率の劣化の分析
    図 4: 失敗率の劣化の分析

    図 4: 失敗率の劣化の分析

     

     

    IIS の「Session」モジュールとは

    それでは、応答時間の割合として最も高かった、「Session」モジュールとは何でしょうか。これは、セッションデータを管理するモジュールです。セッションデータとは、ブラウザがWebシステムにアクセスしてから終了するまでサーバー側で保持しておくデータです。
     
    例えば、ECサイトで商品をカートに入れた場合、他のページに遷移してもカートの中身が変わりません。これは、サーバーがブラウザごと=セッションごとのデータを保存しているためです。このセッションごとのデータを管理しているのが、IISの場合には「Session」モジュールです。

     

    図 5:セッションデータとは
    図 5:セッションデータとは

    図 5:セッションデータとは

     

     

     

    それでは、「Session」モジュールの処理が遅延するのはどのような場合でしょうか。IISの「Session」モジュールの遅延についてインターネットで検索すると、「セッションロック」にたどり着きました。
     
    参考文献: Stack Overflow「Session lock causes ASP.Net websites to be slow
     
    セッションロックとは、セッションデータを使用する際に他の処理が読み込めないように制限する機能です。例えば、先ほどのECサイトの例では、カートの中身を変更しながら別タブなどでカートの中身を確認しようとすると、どちらが正しい情報か分からなくなってしまいます。そこで、カートの中身を変更する処理が終わるまではカートの中身を確認する処理の実行を待ってもらうようにロックをかけます。

     

     

    図 6:セッションロックとは
    図 6:セッションロックとは

    図 6:セッションロックとは

     

     

     

    IISの場合、このセッションロックが非常に多く発生します。なぜなら、IISではデフォルトで、セッションデータを変更しない場合でも、すべての処理がセッションデータのロックを取得する仕様となっているためです。
     
    ユーザーが1操作ずつ、読み込みが終わるのを待ってから次の操作に移る場合には問題となりません。しかし、ユーザーが処理完了を待ちきれずに別の操作をしたり、F5キーなどでページを再読み込みすると、前の処理がセッションデータをロックしているため、前の処理が終わるまで待たされます。また、各処理はセッションロックが解除されるのを頻繁に確認するため、処理待ちが蓄積すると、Sessionモジュールには大きな負荷がかかります。

    たしかに、セッションデータの整合性を保つためにセッションロックは必要です。しかし、問題なのは、データの参照だけでもロックを取得する仕様となっているという部分です。この仕様により、ページの読み込みのたびにセッションロックが発生し、Sessionモジュールの負荷が発生しているという事実はあまり知られていないのではないでしょうか。

     

    今回のレスポンス遅延では、IISのSessionモジュールの応答時間が長かったため、あるユーザーが処理を待たずに別の操作や再読み込みを繰り返したのではないかと推測しました。また、続いて、どのユーザーのどのような操作が原因だったのか、という確認に進みました。

     

     

    エラーメッセージ「The request queue limit of the session is exceeded.」

    根本原因となるユーザーの調査にあたり、着目したのが、もうひとつの根本原因であるエラーメッセージです。このエラーメッセージについてインターネットで検索すると、ASP.NET 4.7の機能拡張に関する情報が見つかりました。

     

    参考文献: Microsoft社「Throttle concurrent requests per session

     

    従来のバージョンでは、特定のユーザーが一度に複数のページを開いたり、再読み込みを繰り返すと、セッションロック待ちのキューが蓄積され続けていました。そこで、ASP.NET 4.7では、キューに入れられたリクエスト数をカウントし、制限(デフォルトは50個)を超えた場合はリクエストを強制終了するように変更されました。エラーメッセージ「The request queue limit of the session is exceeded.」は、あるセッションでキューの数が実際に制限値を超えた状況を示しています。

     

    そのため、このエラーが発生した処理のリクエスト元ユーザーを確認し、該当ユーザーの操作内容を確認しました。

     

     

    エラー発生リクエストを実行したユーザーの確認

    IISログやDynatrace分散トレースで該当のエラーが発生しているリクエストをご確認いただいたところ、特定の1ユーザーでエラーが多発していました。さらに、同じURLに対して同じユーザーからマイクロ秒単位まで同じタイミングでリクエストを受け付けていました。

     

     

    図 7: 分散トレース
    図 7: 分散トレース

    図 7: 分散トレース

     

     

     IISのセッションロックの仕様上、すべてのリクエストはセッションロックを取得しようとしますが、まったく同じタイミングでロックを取得しようとするとどうなるのでしょうか。推測ですが、デッドロックのように複数のリクエストがロックをつかみあって処理が進まない可能性もあります。今回の原因は、このマイクロ秒単位まで同じタイミングで発行された複数のリクエストであると推定しました。

     

     

    ユーザー操作の確認

    それでは、なぜマイクロ秒単位まで同じタイミングでリクエストが発生したのでしょうか。該当リクエストが発生したユーザー操作の確認のため、Dynatraceのセッションリプレイも確認しました。セッションリプレイとは、ユーザーのクリック、スクロール、文字入力などの操作を記録し、ビデオのように再生する機能です。今回のように、サーバーが受け付けたリクエストだけでなく、ユーザー操作まで追いたい場合に効果を発揮します。

     

     

    図 8: セッションリプレイ(※イメージ図)
    図 8: セッションリプレイ(※イメージ図)

    図 8: セッションリプレイ(※イメージ図)

     

     

    セッションリプレイの確認結果

    • 該当ユーザーではクライアント側の通信速度が遅く、度々「通信エラー」が起きている
    • 今回のエラーが発生した処理は「帳票作成状況確認」で、帳票作成が完了するまで、裏で5秒に1回確認リクエストが発行される
    • 処理中モーダルの表示時間が長いため、待ちきれずに処理完了前にモーダルを閉じている
    • モーダルを閉じる処理にも時間がかかっており、閉じる処理の最中にブラウザを再読み込みしている

     

     

    テスト環境で同様の操作を実施しても、事象は再現されませんでした。

    結局、下記のような状況下で発生した事象と結論付けられました。


    1. 1.    クライアント側の通信品質が悪い時に「帳票作成状況確認」の5秒に1回のリクエストが滞留した
      2.    通信状態が回復したときに一気にリクエストがサーバー側に発行され、マイクロ秒単位まで同じリクエストが発生
      3.    マイクロ秒単位まで同じリクエストがセッションロックをつかみ合い、お互いの処理待ちにより、処理が進まない事態が発生
      4.    セッションモジュールの負荷が上がり、IIS全体に影響

     

     

    解決策

    ユーザー操作の確認結果から、サーバー側の動作に問題はなく、クライアント側の通信速度が問題であるという結論に至りました。

     

    サーバー側でできる対策としては、IISのセッションロックを取得しないように設定変更が可能です。IISではデフォルトで、すべてのリクエストがセッションロックを取得します。しかし、セッション情報を変更しないページの場合、読み取り専用(ReadOnly)と宣言すると、セッションロックを取得しなくなります。これにより、たとえマイクロ秒単位まで同じセッションから同じタイミングでリクエストが発行されたとしても、同時並行で処理ができるので、リクエストの滞留を抑制可能です。

     

     

    図 9:ReadOnlyの場合
    図 9:ReadOnlyの場合

    図 9:ReadOnlyの場合

     

    実装方法は下記のとおりです。

     

    • ページ単位に指定する場合、ページソースに下記を記載します。
      <% @Page EnableSessionState="ReadOnly" %>

      設定例:
        1. <%@ Page EnableSessionState="ReadOnly" %>
        2. <!DOCTYPE html>
        3. <html>
        4. <head>
        5.   <title>My ASP.NET Page</title>
        6. </head>
        7. <body>
        8.   <!-- ページの内容 -->
        9. </body>
        10. </html>

     


    •  「Web.config」を利用して、特定のページ単位や、特定のフォルダ以下すべてのページなどに設定することも可能です。
      設定例:
        1. <configuration>
        2.  <location path="xxx">
        3.     <system.webServer>
        4.        <pages enableSessionState="ReadOnly" />
        5.     </system.webServer>
        6.   </location>
        7. </configuration>

     

    設定方法の詳細は以下の参考文献も確認してください。
     
    参考文献: Microsoft社「Locking Session-Store Data
    参考文献: Stack Overflow「Session lock causes ASP.Net websites to be slow
     
    また、同様の事象の早期発見のため、エラーメッセージ「The request queue limit of the session is exceeded.」についてアラートを設定しました。

     

     

    まとめ

    本記事では、IISのセッション管理の仕様として、下記のようなパフォーマンス上の注意点を解説しました。

     

    • デフォルトではすべての処理がセッションデータのロックを取得する
    • 同一セッションで大量のリクエストが発生すると、セッションロック待ちが蓄積し、システム全体のパフォーマンスに影響がある
    • サーバー側でできる解決策としては、セッション情報を変更しないページの場合、読み取り専用(ReadOnly)と宣言する
       

    また、IISのWebサーバーにOneAgentを導入済みの環境であれば、以下の観点から「セッション管理」の負荷状況をご確認いただけます。

     

    • 応答時間の内訳で、IISの「Session」モジュールの応答時間が長くなっていないか
    • エラーメッセージ「The request queue limit of the session is exceeded.」が出力されていないか

     

    これらの確認により、IISの「セッション管理」の負荷が高いと判断されるWebシステムについては、対策としてセッション情報を変更しないページの場合、読み取り専用(ReadOnly)と宣言するなど、対処方法をご検討いただければと存じます。
     
    本記事が少しでも皆様のお役に立てば幸いです。

     

     

     

     

     

     

    執筆者

    N.T. 

    営業技術本部 カスタマーサクセス統括部 Dynatrace技術サービス部 

    お客様のビジネス価値向上を目的に、Dynatraceを中心とした製品の利活用支援を担当
    個々のお客様の環境に深く入り込み、製品利用状況や事例を収集し、より目的に沿った活用を提案

    ■経歴
    2013年 入社
    2014年 品質管理部隊へ配属、10月からお客さまサポート部隊へ異動
    2025年 Dynatrace Professional資格の取得。Dynatrace技術サービス部へ異動

    プライベートでは二児の母。仕事と家庭の両立に奮闘。
    最近ではようやく生活が落ち着き、Dynatrace Professional資格の取得や新部署への異動など、新たな挑戦に取り組み中。

    関連記事