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 响应状态