1. 程式人生 > 其它 >Httpclient在3.1上成功執行,但更新到.net 5中連線超時(System.Net.Sockets.SocketException (10060))

Httpclient在3.1上成功執行,但更新到.net 5中連線超時(System.Net.Sockets.SocketException (10060))

最近專案中要和外部介面對接,使用了IHttpClientFactory建立Httpclient對API請求 專案在.net core 3.1上完美執行,升級到.net 5,然後出現大批請求超時錯誤。

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (api.map.baidu.com:80)
       ---> System.Net.Sockets.SocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
         at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
         at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
         at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|283_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnectionPool.DefaultConnectAsync(SocketsHttpConnectionContext context, CancellationToken cancellationToken)
         at System.Net.Http.ConnectHelper.ConnectAsync(Func`3 callback, DnsEndPoint endPoint, HttpRequestMessage requestMessage, CancellationToken cancellationToken)
         --- End of inner exception stack trace ---
         at System.Net.Http.ConnectHelper.ConnectAsync(Func`3 callback, DnsEndPoint endPoint, HttpRequestMessage requestMessage, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
         at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
         at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
         at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
         at MarineSH.Utils.HttpClientHelper.GetAsync(String url, Dictionary`2 headers) in D:\wwwroot\2021\MarineSH\MarineSH.Utils\HttpClientHelper.cs:line 37
         at MarineSH.Core.Service.BaiduApiService.Iidentifyaddress(String txtAddress) in D:\wwwroot\2021\MarineSH\MarineSH.Core\Service\BaiduApiService.cs:line 26
         at MarineSH.Controllers.GraphApiController.getADD(String add) in D:\wwwroot\2021\MarineSH\MarineSH\Controllers\GraphApiController.cs:line 23
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
         at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

使用同樣的程式碼在本地執行,環境一致的情況下,將SDK換成.net core 3.0 請求正常,切換到5.0時就開始請求連線超時,後在百度查詢發現真的太拉了,我還以為這個只有我一個出現這個錯誤,然後在github的.net rutime 專案的Issues中發現這個問題還是有很多人出現的。在查看了一些回覆後可以確定問題是由於.net 5中切換到了雙協議棧,TcpClient將預設為IPV6,這意味這IPV6將用於IPV4和IPV6的請求,這個時候如果你的客戶端或者網路不支援IPV6或雙協議棧,連線將會出現超時。 ==>Httpclient perfectly work on 3.1 but timeout in .net 5

IPv6 測試 (test-ipv6.com)這個網址可以測試你當前網路是否支援IPV6連線,可以看到我當前環境是沒有IPv6地址的。

這個問題的解決方案,net runtime團隊也給出了一個建議,強制使用IPV4:HttpClientHttpClient

就不復制程式碼了,將地址貼出來,如果有好的方案也歡迎大家一起分享:解決方案

這次確定錯誤也讓我對Httpclient有了一些深刻的瞭解,不怎麼會寫文章如果當中有錯誤也歡迎大家指正!最後老老實實把5.0切換到3.0,人和程式碼總得要有個人跑(加狗頭)