【发布时间】:2020-03-22 08:39:59
【问题描述】:
自 2 周以来,通过尝试连接我们的后端系统,我们有时会遇到以下异常:
System.Net.Http.HttpRequestException:未知错误 -1 ---> System.Net.Sockets.SocketException:System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32 端口,CancellationToken cancelToken)出现未知错误 -1 ) --- 内部异常堆栈跟踪结束 --- 位于 System.Threading.Tasks.ValueTask`1.get_Result() 的 System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancelToken) 处
但此时,我可以通过 Postman 调用 API Server。 我调用 API 服务器的代码是这样的:
using (var client = this.ClientFactory(serviceUserName, serviceUserPassword))
{
try
{
using (var response = await client.SendAsync(request, System.Net.Http.HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
{
return checkAction(response);
}
}
catch (HttpRequestException ex)
{
this.logger.LogError(ex, "http error occured while checking availability for " + url);
return false;
}
catch (TaskCanceledException ex)
{
this.logger.LogError(ex, url + " timed out");
return false;
}
catch (Exception ex)
{
this.logger.LogError(ex, url + " general exception!");
return false;
}
}
ClientFactory() 函数的样子
private HttpClient ClientFactory(string serviceUserName, string serviceUserPassword)
{
var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(this.clientTimeoutSeconds);
if (!string.IsNullOrEmpty(serviceUserName) && !string.IsNullOrEmpty(serviceUserPassword))
{
var basicAuthToken = Convert.ToBase64String(Encoding.ASCII.GetBytes(serviceUserName + ":" + serviceUserPassword));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicAuthToken);
}
return client;
}
我不知道如何调试这个问题。 该应用程序位于运行在 kestrel Web 服务器上的 Cloud Foundry 服务器上。
更新
var client = this.ClientFactory(serviceUserName, serviceUserPassword);
try
{
var response = await client.SendAsync(request, System.Net.Http.HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
return checkAction(response);
}
catch (HttpRequestException ex)
{
this.logger.LogError(ex, "http error occured while checking availability for " + url);
return false;
}
catch (TaskCanceledException ex)
{
this.logger.LogError(ex, "availability check for " + url + " timed out");
return false;
}
catch (Exception ex)
{
this.logger.LogError(ex, "availability check for " + url + " general exception!");
return false;
}
ClientFactory() 函数现在的样子
private HttpClient ClientFactory(string serviceUserName, string serviceUserPassword)
{
var client = this.clientFactory.CreateClient();
client.Timeout = TimeSpan.FromSeconds(this.clientTimeoutSeconds);
if (!string.IsNullOrEmpty(serviceUserName) && !string.IsNullOrEmpty(serviceUserPassword))
{
var basicAuthToken = Convert.ToBase64String(Encoding.ASCII.GetBytes(serviceUserName + ":" + serviceUserPassword));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicAuthToken);
}
return client;
}
现在我使用构造函数注入的IHttpClientFactory:
public MyConstructor(IHttpClientFactory clientFactory)
{
this.clientFactory = clientFactory;
}
但这并没有帮助 我仍然得到上面的异常和其他异常,例如:
System.Net.Http.HttpRequestException: Too many open files in system --- System.Net.Sockets.SocketException: Too many open files in system 在 System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) 在 System.Net.Sockets.DualSocketMultipleConnectAsync..ctor(SocketType socketType,ProtocolType protocolType) 在 System.Net.Sockets.Socket.ConnectAsync(SocketType socketType,ProtocolType protocolType,SocketAsyncEventArgs e) 在 System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32 端口,CancellationToken 取消令牌)
所以我的问题又来了,我该如何调试问题?它仅在生产时发生,并且在几个小时或几天后发生......
【问题讨论】:
-
你应该重用 HttpClient,而不是丢弃它。 aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
-
您还需要处理响应。另外,请确保您的系统具有合理的 ulimit linuxhint.com/linux_ulimit_command
标签: c# .net-core dotnet-httpclient socketexception kestrel-http-server