IISでホストされているServiceStackを使用して実装されたAPIがあります。APIの負荷テストの実行中に、応答時間は良好であるが、サーバーあたり約3,500人の同時ユーザーに到達するとすぐに応答時間が急速に低下することがわかりました。2台のサーバーがあり、7,000人のユーザーでサーバーにアクセスすると、すべてのエンドポイントで平均応答時間が500ミリ秒未満になります。ボックスはロードバランサーの背後にあるため、サーバーごとに3,500の同時実行が可能です。ただし、同時ユーザーの合計数を増やすとすぐに、応答時間が大幅に増加します。同時ユーザーをサーバーごとに5,000に増やすと、エンドポイントあたりの平均応答時間は約7秒になります。
サーバーのメモリとCPUは非常に低く、応答時間は良好ですが、劣化した後も同様です。10,000人の同時ユーザーのピーク時には、CPUの平均は50%をわずかに下回り、RAMは16のうち約3〜4 GBになります。以下のスクリーンショットは、合計10,000人の同時ユーザーによる負荷テスト中のperfmonのいくつかの主要なカウンターを示しています。強調表示されているカウンターは要求/秒です。スクリーンショットの右側では、1秒あたりのリクエスト数のグラフが非常に不安定になっていることがわかります。これは、応答時間が遅い場合の主な指標です。このパターンを見るとすぐに、負荷テストで応答時間が遅いことに気付きます。
このパフォーマンスの問題をトラブルシューティングするにはどうすればよいですか?これがコーディングの問題か構成の問題かを特定しようとしています。この動作を説明できるweb.configまたはIISの設定はありますか?アプリケーションプールは.NET v4.0を実行しており、IISバージョンは7.5です。デフォルト設定から行った唯一の変更は、アプリケーションプールのキューの長さの値を1,000から5,000 に更新することです。また、次の構成設定をAspnet.configファイルに追加しました。
<system.web>
<applicationPool
maxConcurrentRequestsPerCPU="5000"
maxConcurrentThreadsPerCPU="0"
requestQueueLimit="5000" />
</system.web>
詳細:
APIの目的は、さまざまな外部ソースからのデータを組み合わせてJSONとして返すことです。現在、InMemoryキャッシュの実装を使用して、データレイヤーで個々の外部呼び出しをキャッシュしています。リソースへの最初の要求は、必要なすべてのデータをフェッチし、同じリソースに対する後続の要求はキャッシュから結果を取得します。特定の設定間隔でキャッシュ内の情報を更新するバックグラウンドプロセスとして実装される「キャッシュランナー」があります。外部リソースからデータを取得するコードの周りにロックを追加しました。また、エンドポイントが最も遅い外部呼び出しと同じくらい遅くなるように非同期の方法で外部ソースからデータをフェッチするサービスを実装しました(もちろんキャッシュにデータがある場合を除きます)。これは、System.Threading.Tasks.Taskクラスを使用して行われます。プロセスで使用できるスレッドの数の点で制限にぶつかりますか?