HttpClient GetAsync 随机失败

Posted

技术标签:

【中文标题】HttpClient GetAsync 随机失败【英文标题】:HttpClient GetAsync fails randomly 【发布时间】:2015-08-04 19:03:10 【问题描述】:

我在多个多线程消费者中使用 .net HTTPClient,以每秒一次向本地服务发出 GetAsync Web 请求 127.0.0.1。

Web 请求在 99.9% 的时间内完成,但偶尔有一些请求(超过 3-4 小时)会卡在 GetAsyc 中,无法完成或超时。在同一时间段内对同一服务 url/端口的请求将正常工作,新请求将正常完成。

GetAsync 以“即发即弃”模式被触发,其中在完成时调用回调以处理生成的解析数据(因为它与一些不使用异步的旧代码集成。)

public void Execute(Action<IAsyncCommand> onCompletion)

    this.onAsyncCompletion = onCompletion;
    try
    
       // do not await as this is fire and forget
       this.HandlRequestAysnc(this.Target, new StringContent(this.CommandPayload));
        return;
    
    catch(Exception e)
    
      //log exception
    
 
private async Task HandlRequestAysnc(Uri uri, StringContent stringContent)

    try
    
        ConfiguredTaskAwaitable<HttpResponseMessage> request = stringContent != null ? webClient.PostAsync(uri, stringContent).ConfigureAwait(false) : webClient.GetAsync(uri).ConfigureAwait(false);
        //this will never return or timeout 1 in 10000 times
        using (HttpResponseMessage response = await request) 
        
            if (response.IsSuccessStatusCode)
            
                using (HttpContent content = response.Content)
                
                    string result = await content.ReadAsStringAsync(); 
                    //handle result
                
            
            else
            
             //handle failure
            
        
    
    catch (Exception ex)
    
         //log exception
    
    if (this.onAsyncCompletion != null)
    
        this.onAsyncCompletion(this);
    

【问题讨论】:

这里一切正常。也许远程服务器根本没有响应?设置超时并测试超时是否有效。向我确认您测试了超时。 我已经测试了超时,它在测试过程中可以正常工作。我可以用断点阻止我的服务,并将在我的 .net 代码中收到超时。 HTTPClient 设置如下: private HttpClient webClient = new HttpClient(new HttpClientHandler() AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip ) MaxResponseContentBufferSize = 10000000, Timeout = TimeSpan.FromSeconds(150) ; 您是否在应用中的任何位置使用结果或等待? 否——任务从不等待,我们从不访问结果。我们试图寻找死锁条件,但它似乎不存在。这似乎也只发生在每 10000 次左右的请求中...... 我们最终添加了一些代码来检查正在运行的任务(现在需要一个取消令牌)并在它们被卡住太久时取消它们。这似乎可行,因为它将从 GetAsync 返回......虽然我仍然想深入了解这一点。 【参考方案1】:

GetAync 的一个问题是,一旦会话开始,TCP 堆栈就会受到控制。最近的一项实验室实验证明,启动 10,000 个 get 请求(用于调查我们在 prod 环境中出现内存问题的原因)需要 5 分钟(在应用程序结束后)让 TCP 堆栈清理所有内容。

如果您发现套接字状态具有 Fin-Wait 1 或 2、Time-Wait 或其他半生不熟的会话,这只是两个系统之一(或两者)无法处理流量的更大问题的征兆以这个速度。一旦这种情况开始发生,事情就会迅速失控,因为双方都在努力维持会议,但都在失去足够快的资源来做到这一点。

此类问题的解决方案是寻找另一种提高吞吐量的方法。

【讨论】:

以上是关于HttpClient GetAsync 随机失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# (.NET 4.5) 中为 HttpClient.GetAsync(URI) 创建回调?

连接到 *** 时 HttpClient.GetAsync 超时

HttpClient.GetAsync,无效的 URI 异常

使用 HttpClient.GetAsync() 时如何确定 404 响应状态

HttpClient.GetAsync 一次只执行 2 个请求?

如何阻止 HttpClient.GetAsync(uri) 挂起? [复制]