3

ユーザーが PDF をアップロードして WORD 文書に変換できる Web サイトがあります。

それはうまく機能しますが、時々(1時間に5〜6回)、ユーザーは変換が行われるまで通常よりも長く待たなければなりません....

私はASP.NET MVCを使用しており、フローは次のとおりです。-ユーザーがファイルをアップロード->ストリームを取得して単語に変換->単語ファイルを一時ファイルとして保存->ユーザーにURLを返す

このフローを非同期に変換する必要があるかどうかわかりません。基本的に、私のフローは現在シーケンシャルですが、1 秒あたり約 3 ~ 5 のリクエストがあり、CPU はデュアル コアで 4 GB RAM です。

そして、私が知っているようにmaxConcurrentRequestsPerCPU is 5000; またThe default value of Threads Per Processor Limit is 25; したがって、これらのデフォルト設定は問題ないはずですよね?

では、なぜ私のWebアプリには「待機」があるのですか? デフォルトから他のものに変更する必要があるIIS設定はありますか、それとも変換の同期方法を非同期にする必要がありますか?

Ps: PDF ファイルのサイズに応じて、変換自体に 1 秒から 40 ~ 50 秒かかります。

更新:基本的に、私にとってあまり明確ではないのは、ユーザーがファイルをアップロードし、変換が長い場合、現在のリクエストだけが「苦しむ」べきではないということです? 次のリクエストは独立しているので、別の CPU コールと別のスレッドを作成するので、ここで待機する必要はありませんね。

4

1 に答える 1

1

ここで明確に定義しなければならないことがいくつかあります。少なくとも私が理解できる限り、Async(hronous) メソッドとフローは同じものではありません。

非同期メソッド (Task を使用し、通常は async/await キーワードも利用) は、次のように機能します。

  1. スレッド t1 で実行が開始され、await に到達するまで
  2. (潜在的に) 長い操作は、スレッド t1 では実行されません。IOCP (I/O 完了ポート) を利用して、アプリ スレッドでさえ実行されない場合があります。
  3. スレッド t1 は解放されてスレッド プールに戻され、必要に応じて他の要求を処理する準備ができています。
  4. (潜在的に) 長い操作が返されると、スレッドがスレッドプールから取得され (同じ t1 または、おそらく別の t1 である可能性があります)、残りのコード実行は、最後に検出された await から再開されます。
  5. 残りのコードが実行されます

ここで注意すべき点がいくつかあります。

を。プロセス全体でクライアントがブロックされます。スレッドの最終的な切り替えなどは、サーバー上でのみ発生します。このアプローチは、主に「スレッドの枯渇」と呼ばれる望ましくない状態を軽減するために設計されています。クライアントの合計待ち時間を短縮することを意図したものではなく、通常はプロセスを高速化することはありません。

私が理解している限りでは、非同期フローとは、少なくともこの場合、ドキュメントを変換するというユーザーの要求の後、クライアント (つまり、クライアントのブラウザー) は、これが通知された応答をすぐに受け取ることを意味します。サーバー上で長いプロセスが開始された可能性があります。ユーザーは辛抱する必要があり、この現在の応答ページで進行状況のフィードバックが提供される場合があります。


あなたの場合、最初のアプローチはまったく役に立たないため、2 番目のアプローチをお勧めします。

もちろん、これは簡単ではありません。キューをエミュレートする必要があり、処理エージェントとエビクション ポリシーが必要です (2 番目のエージェントが必要ない場合は、ほとんどの場合、同じエージェントによって強制されます)。

これは次のように機能します。

を。a. エンド ユーザーがファイルを送信すると、Web サーバーがそれを受信します。Web サーバーはそれをキューに入れ、ジョブ番号 c を受け取ります。Web サーバーは、ジョブ番号を含む応答をユーザーに返します (サーバーから定期的に進行状況を受け取るポーリング メカニズムを備えた HTML ページとしましょう)。エージェントは、機会があればドキュメントの処理を開始し (つまり、他の作業が終了すると)、Web サーバーがこの情報を取得できるように共通の場所でそのステータスを更新します。Web サーバーは、HTML 応答からジョブのステータスを要求する呼び出しを受信し、ジョブが完了したことを確認して、ダウンロード リンクを提供するか、直接ダウンロードを開始します。

これは、いくつかの方法で洗練できます。

  1. クライアントがサーバーをポーリングする代わりに、Websocketsまたはロング ポーリング (たとえば、SignalRが両方をカバー) を使用できます。
  2. ハードウェア構成が理にかなっていれば、1 つではなく多くの処理エージェントを使用できます。

キューは単純な RDBMS で実装できます。Remus Rușanu はこれについて素晴らしい記事を書いています。

于 2016-07-07T20:17:47.787 に答える