1分あたり数千のリクエストは大きい ロード、およびそれを正しく行う唯一の方法は、一度に実行できるスレッドの最大数を制御および制限することです。
これをどのように実装したかについてはあまり情報が投稿されていないためです。考えられるいくつかの状況について説明します。
実験する時間...
定数:
- 処理するアイテム:
- 1秒あたり50 、つまり...
- 1分あたり3,000 、そしてそれを見るもう1つの方法...
- 1時間あたり180,000
変数:
-
データ転送速度:
-
1秒間に転送できるデータの量は、私たちが何をしようとも影響を及ぼします。これは、時間帯によって1日を通して異なります。
私たちができる唯一のことは、さまざまなCPUからより多くのリクエストを送信して、送り返すトラフィックの重みを分散させることです。
-
-
処理能力:
-
これは
WebJobにあると思います これをMVCサイト内にコーディングするのとは対照的に、それは自己です。それは非常に非効率的であり、あなたが達成しようとしている目的には適合しません。 WebJobを使用することで、キューできます。 他のWebJobsによって処理される作業項目 。 キュー 問題は、Azureキューです。ストレージ 。
-
問題:
- 1秒あたり50のトランザクションを完了しようとしているため、50のスレッドを使用している場合、各トランザクションは1秒以内に完了する必要があります。 45秒のタイムアウトは、現時点では何の役にも立ちません。
- 50個のスレッドが同時に実行され、すべてが1つのCPUで1秒ごとに1秒以内に完了することを期待しています。 (ここでは、要点を誇張しています...しかし、毎秒50個のテキストファイルをダウンロードすることを想像してください。それを処理してから、同僚が準備ができていることを期待して、同僚にそれを撃ち返すことを試みます。キャッチ)
- 再試行ロジックを設定する必要があります。3回試行してもアイテムが処理されない場合は、キューに戻す必要があります。理想的には、サーバーが応答するまでに、障害が発生するたびに1秒よりも多くの時間を提供する必要があります。たとえば、最初の障害で2秒の休憩を与え、次に4秒、次に10秒の休憩を与えたとすると、これにより、持続する確率が大幅に高まります。 /必要なデータを取得します。
- 私たちは想定しています そのMongoDb 1秒あたりのこの数のリクエストを処理できます。まだ行っていない場合は、スケールアウトする方法を検討し始めてください。問題は、MongoDbであるという事実ではなく、データレイヤーが何かである可能性があります。これは、この数のリクエストを問題の原因として最も可能性が高い単一のソース。
解決策:
-
WebJobを設定しますEnqueueJobという名前を付けます 。このWebJobQueue Storageで処理される作業項目をキューに入れるという1つの唯一の目的があります 。 Queue Storage Containerを作成します 名前付きWorkItemQueue、このキューは次のステップへのトリガーとして機能し、スケールアウト操作を開始します。- 別の
WebJobを作成しますDequeueJobという名前 。このWebJobまた、WorkItemQueueから作業項目をデキューするという1つの唯一の目的があります。 データストアへのリクエストを送信します。 -
DequeueJobを構成します アイテムがWorkItemQueue内に配置されたらスピンアップします 、それぞれで5つの個別のスレッドを開始し、キューが空でない間に、各スレッドの作業項目をデキューして、デキューされたジョブの実行を試みます。- 1を試みます。失敗した場合は、待ってから再試行します。
- 2回試行します。失敗した場合は、待機して再試行します。
- 試行3、失敗した場合は、アイテムを
WorkItemQueueにエンキューします
- x個のCPUに自動スケールアウトするようにWebサイトを構成します(WebサイトとWebジョブは同じリソースを共有することに注意してください)
これが10分間の短いビデオです キューストレージとWebジョブの利用方法の概要を説明します。
編集:
これらのエラーが発生する可能性があるもう1つの理由は、他の2つの要因が原因である可能性があります。これも、MVCアプリにあることが原因です...
DEBUGを使用してアプリケーションをコンパイルする場合 属性が適用されましたが、RELEASEをプッシュしています 代わりに、web.configの設定が原因で問題が発生する可能性があります。 、DEBUGなし 属性の場合、ASP.NET Webアプリケーションは最大90秒間リクエストを実行します。リクエストにこれより長い時間がかかる場合は、リクエストを破棄します。
タイムアウトを90秒より長くするには [httpRuntime][3]を変更する必要があります web.configのプロパティ ...
<!-- Increase timeout to five minutes -->
<httpRuntime executionTimeout="300" />
もう1つ注意する必要があるのは、ブラウザーのリクエストタイムアウト設定> Webアプリです。コードを抽出してWebJobに配置するのではなく、MVCにコードを保持することを主張する場合は、次のコードを使用して、Webアプリにリクエストを送信し、リクエストのタイムアウトを相殺できます。
string html = string.Empty;
string uri = "https://google.com";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Timeout = TimeSpan.FromMinutes(5);
using (HttpWebResponse response = (HttpWebResonse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}