質問

運用サーバーで奇妙な状況が発生しています。asp.net の接続はキューに入れられますが、CPU は 40% しかありません。また、データベースは 30% の CPU で正常に動作します。

コメントでリクエストされたその他の履歴:

  • ピーク時には、サイトには 1 時間あたり約 20,000 人の訪問者が訪れます。
  • このサイトは、多くの AJAX/POST を備えた asp.net Web フォーム アプリケーションです。
  • このサイトはユーザーが作成したコンテンツを多く使用しています
  • サイトで使用されるデータベースと Web サービスにアクセスするテストページを使用して、サイトのパフォーマンスを測定します。このページは、通常のロードでは 1 秒以内に提供されます。リクエストに 4 秒以上かかる場合、アプリケーションが遅いと定義します。
  • 測定結果から、接続時間は速いものの、処理時間が長いことがわかります。
  • 単一のリクエストに対する応答の遅さを正確に特定することはできません。サイトは通常の時間帯は正常に動作しますが、ピーク時間帯には遅くなります。
  • サイトが CPU バウンド (つまり 100% で実行される) になるという問題があったため、それを修正しました。
  • また、appdomain を再起動する際の例外に関する問題もありましたが、それを修正しました。
  • ピーク時間帯には、asp.net パフォーマンス カウンターを確認します。現在の接続数が 600 で、キューに入れられた接続が 500 であるという動作が確認できます。
  • ピーク時の CPU 使用率は約 40% (CPU バウンドではないと思われます)
  • 物理メモリが約 60% 使用されています
  • ピーク時には、データベースサーバーの CPU は約 30% になります (データベースに依存していないと思われます)

私の結論は、サーバーによるリクエストの高速な処理を他の何かが妨げているということです。容疑者の可能性

  • デッドロック (!syncblk はロックを 1 つだけ提供します)
  • ディスク I/O (sysinternals processexplorer 経由でチェック)3.5mB/秒)
  • ガベージコレクション (ピーク時 10 ~ 15%)
  • ネットワーク I/O (接続時間はまだ短い)

プロセスが何をしているのかを知るために、ミニダンプを作成しました。

20 秒間隔で 2 つの MemoryDump を作成することができました。これは最初の出力です:

!threadpool
CPU utilization 6%
Worker Thread: Total: 95 Running: 72 Idle: 23 MaxLimit: 200 MinLimit: 100
Work Request in Queue: 1
--------------------------------------
Number of Timers: 64

そして 2 番目の出力:

!threadpool
CPU utilization 9%
Worker Thread: Total: 111 Running: 111 Idle: 0 MaxLimit: 200 MinLimit: 100
Work Request in Queue: 1589

ご覧のとおり、キューには大量のリクエストがあります。

質問1: キューに 1589 件のリクエストがあるということは何を意味しますか。何かがブロックしているということですか?

!threadpool リストには、主に次のエントリが含まれます。不明な機能:6a2aa293 コンテキスト:01cd1558 asynctimercallbackcompletion timerinfo@023a2cb0

AsyncTimerCallbackCompletion を詳しく理解すると、

!dumpheap -type TimerCallback

次に、TimerCallback 内のオブジェクトを調べます。それらのほとんどは次のタイプです。

System.Web.SessionState.SessionStateModule
System.Web.Caching.CacheCommon

質問2: これらのオブジェクトにタイマーなどが付いていることに意味はあるのでしょうか?これを阻止すべきでしょうか。そしてどうやって?

主な質問 接続をキューに入れて CPU を最大限に活用しない理由は、明らかな問題を見逃しているからでしょうか?


ピーク時にクラッシュダンプを作成することに成功しました。debugdiag で分析すると、次の警告が表示されました。

Detected possible blocking or leaked critical section at webengine!g_AppDomainLock owned by thread 65 in Hang Dump.dmp
Impact of this lock
25.00% of threads blocked
(Threads 11 20 29 30 31 32 33 39 40 41 42 74 75 76 77 78 79 80 81 82 83)

The following functions are trying to enter this critical section
webengine!GetAppDomain+c9

The following module(s) are involved with this critical section
\\?\C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\webengine.dll from Microsoft Corporation

Google で簡単に検索しても結果は得られません。誰かが手がかりを持っていますか?

役に立ちましたか?

解決

キューを処理するワーカー プロセスが実際の取引の最大の要因でした。おそらく、同じホスト上の Web サービスを呼び出す Web サイトに接続されています。したがって、一種の行き詰まりが生じます。

machine.configを次のように変更しました。

<processModel
        autoConfig="false"
        maxWorkerThreads="100"
        maxIoThreads="100"
        minWorkerThreads="50"
        minIoThreads="50" />

標準では、この processModel は autoConfig="true" に設定されています

新しい構成では、Web サーバーはキューに入れられないほど高速にリクエストを処理します。

他のヒント

私は realworldcoder と一緒です:IIS は、ワーカー プロセスに受信リクエストを処理させることで機能します。リクエストが積み重なると、実際に発生しているように見え、パフォーマンスが急激に低下します。

実行/確認できることがいくつかあります。

  1. SQL Server でアクティビティ モニターを起動します。どのクエリに最も時間がかかっているかを確認し、結果に応じて実行時間を短縮するために変更を加えたいと考えています。クエリが長いと、ページが実行されているスレッドがブロックされ、サポートできる接続の数が減少する可能性があります。

  2. これらの page/ajax 呼び出しのクエリの数と実行にかかる時間を調べてください。特定のメソッドのみを実行する必要がある場合でも、.Net はページ サイクル全体を実行するため、Ajax 呼び出しに対して実行される数十の不要なクエリを含むページを見たことがあります。これらの呼び出しを通常の Web ハンドラー (.ashx) ページに分割すると、何が起こるかを正確に制御できるようになります。

  3. IIS が受信要求を処理する必要があるワーカー プロセスの数を増やすことを検討してください。新しいアプリ プールのデフォルトは 1 プロセスです。 20スレッド. 。通常、大量のリクエストを処理するにはこれで十分です。ただし、DB サーバーまたはその他のリソースで待機しているためにリクエストがブロックされている場合、パイプラインがスタックする可能性があります。これは、アプリケーションのパフォーマンスと通常の機能の両方にプラスまたはマイナスの影響を与える可能性があることに留意してください。したがって、いくつかの調査を行ってから、テスト、テスト、テストを繰り返します。

  4. セッションの使用量を減らすか排除することを検討してください。いずれにせよ、メモリ使用量を確認すると、Web サーバーにさらに RAM が追加される可能性があります。セッション データは、データが使用されているかどうかに関係なく、ページの読み込み (Ajax 呼び出しを含む) ごとにシリアル化および逆シリアル化されます。セッションに何を保存しているかによっては、サイトに重大な悪影響を与える可能性があります。使用していない場合は、web.config で完全にオフになっていることを確認してください。セッションを Web サーバーの外に保存すると、ページがセッションを取得して保存するときにネットワークの速度に制限されるため、これらの問題はさらに悪化することに注意してください。

  5. JIT (Just-In-Time) コンパイルに関するサイトのパフォーマンス カウンターを確認してください。これはほぼ存在しないはずです。大量の JIT によってサイトが崩壊するのを見てきました。それを排除するためにそれらのページが再コード化されると、サイトは再び飛び始めました。

  6. さまざまなキャッシュ戦略を検討してください (私はセッションが実際のキャッシュ ソリューションであるとは考えていません)。おそらく、常に DB サーバーから引き出す必要がない、常にリクエストするものがあるかもしれません。私の友人は、ディスカッション グループを含む動的コンテンツの物理ファイルとして Web ページ全体をキャッシュするサイトを持っています。これにより、パフォーマンスが大幅に向上しました。しかし、これはアーキテクチャ上の大きな変更です。

上記は、注目すべき点のほんの一部です。基本的に、何が起こっているのかを正確に知るには、さらに詳細に調査する必要がありますが、通常のパフォーマンス カウンターのほとんどでは、そこまで明確なものは得られません。

ASP.NET キューに入れられた要求が多すぎると、パフォーマンスが低下します。リクエスト スレッドの数は非常に限られています。

ページの遅い部分を非同期で処理するか、ページの実行時間を短縮するためにできることは何でもして、これらのスレッドを解放してください。

これが古いスレッドであることは承知していますが、ASP.NET サイトのパフォーマンスが低い人にとって、Google で最初にヒットするスレッドの 1 つです。そこで、いくつかの推奨事項を紹介します。

1) 非同期プログラミングは根本原因を解決します。実際のビジネス ロジックを実行するために Web サービスを呼び出している間、それらのリクエスト スレッドは応答を待っているだけです。代わりに、別の受信リクエストを処理するために使用できます。これにより、キューの長さが完全になくなるわけではないにしても、大幅に短縮されます。非同期プログラミングは、個々のリクエストのパフォーマンスではなく、スケーラビリティを重視します。これは、.NET 4.5 では次のように非常に簡単に実現できます。 非同期/待機 パターン。ASP.NET は 1 分あたり 2 の速度でスレッドを挿入するため、既存のスレッドを再利用しない限り、サイトの負荷がすぐに足りなくなってしまいます。さらに、より多くのスレッドをスピンアップすると、パフォーマンスが若干低下します。より多くの RAM が必要になり、その RAM を割り当てるのに時間がかかります。machine.config のスレッド プール サイズを増やすだけでは、根本的な問題は解決されません。CPU を追加しない限り、スレッドを追加しても実際には役に立ちません。これはやはりリソースの割り当てが間違っているためです。また、スレッドが多すぎて CPU が少なすぎると、コンテキストが切り替わって死に至る可能性もあります。

2) IIS 7.5 のスレッドに関する人気の記事より:ASP.NET アプリケーションが Web サービス (WFC または ASMX) または System.Net を使用して HTTP 経由でバックエンドと通信している場合は、connectionManagement/maxconnection を増やす必要がある場合があります。ASP.NET アプリケーションの場合、autoConfig 機能により 12 * #CPU に制限されます。これは、クアッドプロセッサでは、IP エンドポイントに対して最大 12 * 4 = 48 の同時接続が可能であることを意味します。これは autoConfig に関連付けられているため、ASP.NET アプリケーションで maxconnection を増やす最も簡単な方法は、たとえば Application_Start からプログラムで System.Net.ServicePointManager.DefaultConnectionLimit を設定することです。この値を、アプリケーションで使用することが予想される System.Net 同時接続の数に設定します。私はこれを Int32.MaxValue に設定しましたが、副作用はありませんでした。試してみてください。これは実際にネイティブ HTTP スタック、WinHTTP で使用されるデフォルトです。System.Net.ServicePointManager.DefaultConnectionLimit をプログラムで設定できない場合は、 autoConfig を無効にする必要がありますが、それは maxWorkerThreads と maxIoThreads も設定する必要があることを意味します。クラシック/ISAPI モードを使用していない場合は、minFreeThreads または minLocalRequestFreeThreads を設定する必要はありません。

3) 1 時間あたり 20,000 人のユニーク訪問者を獲得している場合は、負荷分散を真剣に検討する必要があります。すべてのユーザーが 1 時間あたり 10 ~ 20 件の AJAX リクエストを実行した場合、バックエンドへの Web サービス呼び出しは簡単に 100 万件以上になることになります。別のサーバーを起動すると、プライマリ サーバーの負荷が軽減されます。これを async/await と組み合わせると、問題に簡単にハードウェアを投入できる (スケールアウト) 良い状況に身を置くことができます。ここには、ハードウェアの冗長性、位置情報、パフォーマンスなど、複数の利点があります。AWS や RackSpace などのクラウド プロバイダーを使用している場合、アプリを含む別の VM をスピンアップすることは、携帯電話から行うことができるほど簡単です。最近のクラウド コンピューティングは安すぎて、キューの長ささえまったくありません。これを行うと、非同期プログラミング モデルに切り替える前でもパフォーマンス上の利点を得ることができます。

4) スケールアップ:サーバーにハードウェアを追加すると、スレッドが追加されたときに安定性が向上するため、役立ちます。スレッドが増えると、より多くの CPU と RAM が必要になります。また、async/await を完全に理解した後でも、可能であれば、これらの Web サービス リクエストを微調整する必要があります。これは、キャッシュ層を追加したり、データベース システムを強化したりすることを意味する場合があります。その単一サーバー上の CPU を最大化する必要はありません。CPU が 80% に達すると、ASP.NET はシステムへの追加のスレッドの注入を停止します。ワーカー プロセスが 0% のままであっても問題はなく、タスク マネージャーによって報告されるシステム全体の CPU 使用率が 80% に達すると、スレッド インジェクションが停止し、リクエストがキューに登録され始めます。ガベージ コレクションでは、サーバー上の CPU 負荷が高いことを検出したときにも、奇妙な現象が発生します。

これがうまくいくことを確認できた人はいますか?私はその回答をウェブ上で見つけましたが、投稿された回答によってこの問題が解決されたという確証はありません。そうは言っても、質問投稿者が答えを提供しているので、あまり信憑性はありません。

最近同じ問題が発生しました:

w3wp.exe__defaultapppoool__pid__3920__date__04_26_2011____10_10_40_42am__109__iis_com+ハングダンプ、このロックのインパクトのあるdate__04_26_2011___ime_10_40__wp.exe__defaultapppoool__pid__pid__3920のスレッドが所有するWebEngineで可能なブロッキングまたは漏れの重要なセクションを検出しました。

4.17%ブロックされたスレッド(スレッド17)次の関数は、この重要なセクションWebEngineを入力しようとしています! V2.0.50727 Microsoft CorporationのWebEngine.dll

これは、さらなるトラブルシューティングのために Microsoft が投稿した推奨事項です。

根本原因分析に基づいたフォローアップのために、次のベンダーが特定されました。この重要なセクションの問題の根本原因を決定するために、次のアプローチを検討してください。

  1. アプリケーション検証者Aで「ロックチェック」を有効にします。次の URL から Application Verifier をダウンロードします。 http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c4a25ab9-649d-4a1b-b4a7-c9d8b095df18&displaylang=enB.次のコマンドを実行して、このプロセスの「ロック チェック」を有効にします。

    Appverif.exe -enable locks -for w3wp.exeC.Application Verifier の詳細については、次のドキュメントを参照してください。 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnappcom/html/appverifier.asp?frame=true

  2. DebugDiag クラッシュ ルールを使用してアプリケーションの例外を監視する

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top