32

ファイルのアップロードを受け入れ、そのファイルを別の HTTP エンドポイントに転送する必要がある ASP.NET Web API アプリケーションを作成しています。

多くのユーザーがそれぞれ 100 MB のファイルをアップロードしようとすると (これは有効なユース ケースです)、アプリケーションのメモリ フットプリントが大きくなり、大きなリクエストの量によっては、このフットプリントが大きくなり、アプリケーションがキールする可能性があることを懸念しています。終わって死ぬ。

理想的には、サーバーの負荷を大幅に軽減するために、Web サーバーがファイルの受信を開始したらすぐに、他の HTTP エンドポイントへのファイルのストリーミングを開始したいと考えています。

このプロセスには名前があると確信していますが、私はそれを知りません。そのため、検索がかなり困難になっています。

私は Web API の応答ストリーミングでかなりの作業を行ってきましたが、これまで要求ストリーミングを考慮する必要はありませんでした。

私が言える最善の方法は次のとおりです。

  • アップロードが完了する前にストリームの処理を開始します。
  • HttpClient を使用して同じ要求をストリーミングし、同じデータを他の HTTP エンドポイントにストリーミングします。

誰かが私にいくつかの指針を提供できますか?

4

1 に答える 1

43

それは興味深い質問です。私はいくつかの一般的な指針を与えるために最善を尽くします。

考慮すべき点はほとんどありません。

1) Web APIはデフォルトでリクエストをバッファリングするため、メモリフットプリントがかなり大きくなる可能性があるという懸念は間違いなく正当化されます。WebAPIを強制的にストリーミングモードでリクエストを処理することができます。

    public class NoBufferPolicySelector : WebHostBufferPolicySelector
    {
       public override bool UseBufferedInputStream(object hostContext)
       {
          var context = hostContext as HttpContextBase;

          if (context != null)
          {
             if (string.Equals(context.Request.RequestContext.RouteData.Values["controller"].ToString(), "uploading", StringComparison.InvariantCultureIgnoreCase))
                return false;
          }

          return true;
       }

       public override bool UseBufferedOutputStream(HttpResponseMessage response)
       {
          return base.UseBufferedOutputStream(response);
       }
    }

次に、サービスを置き換えます。

GlobalConfiguration.Configuration.Services.Replace(typeof(IHostBufferPolicySelector), new NoBufferPolicySelector());

この時点でのWebHostとSelfHostの違いにより、このような変更はWebHostでのみ可能であることに注意してください。エンドポイントがセルフホストの場合、GlobalConfigレベルでストリーミングモードを設定する必要があります。

//requests only
selfHostConf.TransferMode = TransferMode.StreamedRequest;
//responses only
selfHostConf.TransferMode = TransferMode.StreamedResponse;
//both
selfHostConf.TransferMode = TransferMode.Streamed;

以前、WebAPIでの大きなファイルの処理についてブログで詳しく説明しました-http ://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/あなたはそれが役に立つでしょう。

2)次に、を使用する場合HttpClient、.NET 4ではデフォルトでリクエストの本文をバッファリングするため、実際には.NEt4.5を使用する必要があります。

.NET 4を使用する必要がある場合は、HttWebRequest直接操作する必要があります。 - http: //msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowreadstreambuffering.aspx-http : //msdn.microsoft。 com / en-us / library / system.net.httpwebrequest.allowwritestreambuffering.aspx

3)データをクライアントにプッシュする限り、それを実行したい場合は、を使用して確実に可能ですPushStreamContent。Henrikの紹介記事はここにあります-http://blogs.msdn.com/b/henrikn/archive/2012/04/23/using-cookies-with-asp-net-web-api.aspx(Webに基づいていますAPI RCビットなので、いくつかの署名など​​を調整する必要があるかもしれません。)ストリームデータのチャンクをここにプッシュすることについてもブログに書いています-http ://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net -web-api /

編集:リクエストに含まれる場合の例を確認するPushStreamContentには、このサンプルソリューションをご覧ください-http: //aspnet.codeplex.com/SourceControl/changeset/view/bb167f0b0013#Samples/Net45/CS/WebApi/UploadXDocumentSample/ReadMe 。TXT

于 2013-01-22T15:05:42.403 に答える