【问题标题】:HttpClient on WebApi is extremely slowWeb Api 中的 HttpClient 非常慢
【发布时间】:2017-11-24 18:06:20
【问题描述】:

我正在使用 ASP.NET WebApi (ApiController) 为我的应用程序实现代理,并使用 HttpClient 通过我的授权标头发出请求。它工作正常,但速度极慢。下面是主要代码,然后是全局初始化(使用 DefaultConnectionLimit)和 web.config 相关的部分。

如您所见,我已经在实际请求中使用了没有代理和 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;
  }
}

和 Web.Config 的一部分

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

【问题讨论】:

  • 您是否尝试过分析您的应用程序?哪一部分看起来很慢?
  • 当我在 SendAsync 调用上使用 ResponseHeadersRead 时,整个代码运行并且 HttpRequestMessage 返回非常快,但随后 HttpClient 继续直接下载并发送到客户端,这个“流”是真的很慢
  • 会不会是你的代理和下游服务之间的通信不畅?如果您尝试缓冲响应(删除HttpCompletionOption.ResponseHeadersRead)会怎样?单个请求是否缓慢或负载不足?
  • 我尝试缓冲响应和单个调用,示例问题:HttpClient 下载速度很慢
  • 您是否尝试在浏览器或邮递员中执行相同的请求(与代理一样)?似乎服务器之间的网络连接很慢,或者服务器向 http 客户端返回内容很慢。

标签: c# asp.net asp.net-web-api dotnet-httpclient asp.net-web-api-routing


【解决方案1】:

通过删除 web.config 的 &lt;system.diagnostics&gt; 部分解决。似乎它导致了输出过剩并减慢了所有 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    相关资源
    最近更新 更多