1

私はASP.NET WebApi(ApiController)を使用してアプリケーション用のプロキシを実装しており、HttpClientを使用して承認ヘッダでリクエストを行います。それは正常に動作しますが、非常に遅いです。以下はメインコード、次にグローバル初期化(DefaultConnectionLimit)とweb.config関連の部分です。WebApiのHttpClientが極端に遅い

あなたが見ることができるように、私はすでに、実際のリクエストに応じていないプロキシとHttpCompletionOption.ResponseHeadersReadで静的/共有のHttpClientオブジェクトを使用しています。このWebApiエンドポイントは並行して呼び出され、正常に動作します。

コード全体が十分速く実行されますが、ResponseHeadersRead asyncを使用しているときにHttpRequestMessageが返され、残りのボディがダウンロードされてクライアント/呼び出し元に直接ストリームされます。

ここには、問題を示すa videoがあります。私は信じていませんが

public class ProxyController : ApiController 
{ 
    private const string BASE_URL = "https://developer.api.autodesk.com"; 
    private const string PROXY_ROUTE = "api/viewerproxy/"; 


    // HttpClient has been designed to be re-used for multiple calls. Even across multiple threads. 
    // https://stackoverflow.com/questions/22560971/what-is-the-overhead-of-creating-a-new-httpclient-per-call-in-a-webapi-client 
    private static HttpClient _httpClient; 

    [HttpGet] 
    [Route(PROXY_ROUTE + "{*.}")] 
    public async Task<HttpResponseMessage> Get() 
    { 
    if (_httpClient == null) 
    { 
     _httpClient = new HttpClient(new HttpClientHandler() 
     { 
      UseProxy = false, 
      Proxy = null 
     }); 
     _httpClient.BaseAddress = new Uri(BASE_URL); 
    } 

    string url = Request.RequestUri.AbsolutePath.Replace(PROXY_ROUTE, string.Empty); 
    string absoluteUrl = url + Request.RequestUri.Query; 

    try 
    { 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, absoluteUrl); 
     request.Headers.Add("Authorization", "Bearer " + AccessToken); 

     HttpResponseMessage response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); 

     return response; 
    } 
    catch (Exception e) 
    { 
     return new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError); 
    } 
    } 
} 

Global.asaxのは、...すべての要求を処理しますが、あまりにも遅くしているよう

public class Global : System.Web.HttpApplication 
{ 
    protected void Application_Start(object sender, EventArgs e) 
    { 
    GlobalConfiguration.Configure(Config.WebApiConfig.Register); 

    ServicePointManager.UseNagleAlgorithm = true; 
    ServicePointManager.Expect100Continue = false; 
    ServicePointManager.CheckCertificateRevocationList = true; 
    ServicePointManager.DefaultConnectionLimit = int.MaxValue; 
    } 
} 

とWebの一部の接続制限の問題です。 Config

<system.web> 
    <compilation debug="true" targetFramework="4.6" /> 
    <httpRuntime targetFramework="4.6" maxRequestLength="2097151" requestLengthDiskThreshold="16384" requestPathInvalidCharacters="&lt;,&gt;,*,%,&amp;,\,?" /> 
    </system.web> 
+0

アプリケーションのプロファイルを作成しようとしましたか?どの部分が遅いようですか? –

+0

SendAsync呼び出しでResponseHeadersReadを使用しているときにコード全体が実行され、HttpRequestMessageが実際に高速で返されますが、HttpClientは直接ダウンロードを続けてクライアントに送信します。このストリームは実際には遅いです –

+0

プロキシとダウンストリームサービス間の通信は低いですか?別のものは、あなたが応答をバッファリングしようとすると( 'HttpCompletionOption.ResponseHeadersRead'を削除します)?単一のリクエストまたは負荷のために遅いですか? –

答えて

0

web.configの<system.diagnostics>セクションを削除して解決しました。それは出力の過剰を引き起こし、すべてのHttpClient要求を遅くしていたようです。

これは私が使用していたコードで、すべてHttpClient.SendAsyncの呼び出しで遅くなっています。しかし、これは接続の問題を追跡するのに役立ちます:-)

<system.diagnostics> 
    <sources> 
    <source name="System.Net" tracemode="protocolonly" maxdatasize="1024"> 
     <listeners> 
     <add name="System.Net"/> 
     </listeners> 
    </source> 
    <source name="System.Net.Cache"> 
     <listeners> 
     <add name="System.Net"/> 
     </listeners> 
    </source> 
    <source name="System.Net.Http"> 
     <listeners> 
     <add name="System.Net"/> 
     </listeners> 
    </source> 
    </sources> 
    <switches> 
    <add name="System.Net" value="Verbose"/> 
    <add name="System.Net.Cache" value="Verbose"/> 
    <add name="System.Net.Http" value="Verbose"/> 
    <add name="System.Net.Sockets" value="Verbose"/> 
    <add name="System.Net.WebSockets" value="Verbose"/> 
    </switches> 
    <sharedListeners> 
    <add name="System.Net" 
     type="System.Diagnostics.TextWriterTraceListener" 
     initializeData="network.log" 
    /> 
    </sharedListeners> 
    <trace autoflush="true"/> 
</system.diagnostics> 
0

私のAzure WebAppでは、アプリケーションログをVerboseに設定しました。明らかなことは分かっていますが、HttpClientを使ったプロキシを実装するまでは重要なパフォーマンスの問題にはなりませんでした。

関連する問題