1

我正在使用ASP.NET WebApi(ApiController)爲我的應用程序實現代理,並使用HttpClient使用我的授權標頭來發出請求。它工作正常,但速度非常慢。下面是主要代碼,然後是全局初始化(使用DefaultConnectionLimit)和web.config相關的一塊。WebApi上的HttpClient非常慢

正如你所看到的,我已經在使用無代理和HttpCompletionOption.ResponseHeadersRead實際要求的靜態/共享的HttpClient對象。這個WebApi端點並行調用,工作正常。

整個代碼運行速度不夠快,但由於我使用的是ResponseHeadersRead異步,因此將返回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; 
    } 
} 

而且網絡的一部分。配置

<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.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中,我將應用程序日誌記錄設置爲詳細。我知道這是一件顯而易見的事情,但是在實施使用HttpClient的代理服務器之前,它並未成爲重大性能問題。