由于尝试连接后端系统2周以来,我们收到以下异常:
System.Net.Http.HttpRequestException:未知错误-1 ---> System.Net.Sockets.SocketException:System.Net.Http.ConnectHelper.ConnectAsync的未知错误-1(字符串主机,Int32端口,CancellationToken cancelToken )---内部异常堆栈跟踪的结尾---在System.Net.Http.ConnectHelper.ConnectAsync(String host,Int32 port,CancellationToken cancelToken)在System.Threading.Tasks.ValueTask`1.get_Result()
但是现在,我可以通过邮递员调用API服务器。 我的调用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:系统中打开的文件太多--- System.Net.Sockets.SocketException:系统中打开的文件太多 在System.Net.Sockets.Socket..ctor(AddressFamily addressFamily,SocketType套接字类型,ProtocolType协议类型) 在System.Net.Sockets.DualSocketMultipleConnectAsync..ctor(SocketType套接字类型,ProtocolType协议类型) 在System.Net.Sockets.Socket.ConnectAsync(SocketType套接字类型,ProtocolType协议类型,SocketAsyncEventArgs e) 在System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32端口,CancelationToken cancelToken)
所以我的问题再次出现,如何调试该问题?它仅在产品上以及数小时或数天之后出现。
答案 0 :(得分:0)
您应该不始终创建一个新的HttpClient实例。 您应该重用它。如果不重用它,则会遇到套接字耗尽(以及其他一系列问题)。
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
由于您使用的是dotnet核心,因此请查看HttpClientFactory https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
因此,一种快速的解决方法是创建一个新的静态HttpClient而不进行处理。但是随后您会遇到DNS问题,因此不要这样做。 https://github.com/dotnet/corefx/issues/11224
所以:使用HttpClientFactory,微软已经解决了上面提到的所有问题:)