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的代理服务器之前,它并未成为重大性能问题。