HttpClient on WebApi is extremely slow

不打扰是莪最后的温柔 提交于 2019-12-04 04:46:39

问题


I'm implementing a Proxy for my application using ASP.NET WebApi (ApiController) and using HttpClient to make the request with my authorization header. It works fine, but it's extremely slow. Below is the main code, then the Global initialization (with DefaultConnectionLimit) and web.config related piece.

As you can see, I'm already using a static/shared HttpClient object with no Proxy and HttpCompletionOption.ResponseHeadersRead on the actual request. This WebApi endpoint is called in parallel, which works fine.

The entire code runs fast enough, but as I'm using ResponseHeadersRead async, the HttpRequestMessage is returned and the rest of the body is downloaded and streamed directly to the client/caller.

Here is a video showing the problem.

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, although I don't believe is a problem of connection limit as all the requests are processed, but just too slow...

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;
  }
}

And part of the Web.Config

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

回答1:


Solved by removing the <system.diagnostics> section of the web.config. It seems that it was causing an excess of output and slowing down all HttpClient requests.

For the record, this the code I was using and causing the slowness on all HttpClient.SendAsync calls. But this is useful for tracking connection problems :-)

<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>


来源:https://stackoverflow.com/questions/44682818/httpclient-on-webapi-is-extremely-slow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!