我在多个多线程消费者中使用.net HTTPClient,以每秒127.0.0.1的速度向本地服务发出GetAsync Web请求。
网络请求完成99.9%的时间,但偶尔会有一些请求(超过3-4小时)将卡在GetAsyc中,并且无法完成或超时。在同一时间段内对同一服务URL /端口的请求将正常工作,新请求将完成。
GetAsync在fire and forget模式下被触发,其中在完成时调用回调来处理生成的解析数据(因为它与一些不使用异步的旧代码集成。)
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);
}
}
答案 0 :(得分:0)
GetAync的一个问题是,一旦会话启动,TCP堆栈就会受到控制。最近的一个实验室实验证明,为了调查我们在prod环境中遇到内存问题的原因,我们需要花费超过5分钟(在应用程序结束后),以便清理所有内容。
如果您发现套接字状态具有Fin-Wait 1或2,Time-Wait或其他半场烘焙会话,则只是一个较大问题的症状,即两个系统中的一个(或两者)无法处理流量以这个速度。一旦这种事情开始发生,事情就会迅速失去控制,因为双方都在努力维持会议,但正在失去足够快的资源。
解决此类问题的方法是找到另一种提高吞吐量的方法。