今日は、MVC3 Web ロールの AsyncController 内から長時間実行されるブロック プロセス (5 ~ 30 秒) の待機をシミュレートしたいと思いました。ただし、最初は1秒から始めて、物事を進めました。はい、ブロック操作は現在、I/O 完了ポートで外部サービスに対して非同期に実行できないため、これの賢明さには疑問がありますが、この特定の状況でのパフォーマンスの制限を確認したかったのです。
私の Web ロールでは、6 つの小さなインスタンスをデプロイしました。唯一のコントローラーは AsyncController で、1000 ミリ秒のブロッキング操作をシミュレートするための 2 つの単純なメソッドがありました。
MVC3 Web ロール コントローラーは単純に次のとおりです。
public class MessageController : AsyncController
{
public void ProcessMessageAsync(string id)
{
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(() => DoSlowWork());
}
public ActionResult ProcessMessageCompleted()
{
return View("Message");
}
private void DoSlowWork()
{
Thread.Sleep(1000);
AsyncManager.OutstandingOperations.Decrement();
}
}
次に、Amazon EC2 から Web ロールにストレスを適用しました。12 台のサーバーを使用して、負荷をゆっくりと増やし、1 秒あたり 550 リクエストに近づきました。これを超えてプッシュしようとすると、明らかなスレッドの枯渇とそれに続くエラーが発生しました。CLR スレッドの制限に達していたと思いますが、これは CPU あたり 100 スレッドであると理解しています。AsyncController のオーバーヘッドと、1000 ミリ秒のブロッキング操作で 1 サーバーあたり 1 秒あたり平均 550/6 = 92 リクエストという計算は、その結論に合っているようです。
これは本当ですか?他の人が同様のことを言っているのを見たことがあります。このタイプの負荷では、インスタンスあたり 1 秒あたり 60 ~ 80 リクエストに達しました。このシステムの負荷は、主に実行時間の長い操作で構成されるため、5000 ミリ秒のタスクがオンラインになると、1000 ミリ秒で 1 秒あたり 92 のリクエストが大幅に減少します。
ブロッキング I/O のリクエストを複数の個別の Web ロール フロント エンド経由でルーティングして、この負荷をより多くのコアに分散させる以外に、1000 ミリ秒のブロック時間で 1 秒あたり 90 程度のリクエストというこの明らかな制限を超える方法はありますか? ここで明らかな間違いを犯しましたか?