【发布时间】:2017-02-15 11:41:59
【问题描述】:
1 月 17 日 09:32,我们的一项服务突然开始抛出 500 错误。它是第三方服务的适配器服务,我们使用 HttpClient 对其进行 POST(因此我们使用查询字符串参数对我们的服务进行 GET,然后使用 POST 和参数将其传输到第三方应用程序身体)。当我使用邮递员或 curl 手动发布到第三方服务时,它响应良好。所以这是我们服务的问题。它是使用 OWIN 中间件的 .NET 服务,类似于我认为的 .NET core 的工作方式。问题是前段时间,.NET 框架从 4.5.2 升级到 4.6,当在 VS 中这样做时,它在 web.config 中添加了一个<httpRuntime targetFramework="4.5.2"/> 元素。这是为了尽最大努力保留应用程序的现有行为,以防框架版本之间出现任何重大更改。升级的人没有意识到,留在了web.config中的元素中。它工作了很长时间,然后突然在所有环境中同时(包括本地)被破坏了。我认为它一定与 .NET 框架中的时间相关,但回滚我的系统时钟并不能解决它!我可以寻找什么,关于这个谜团的任何想法?只需将 web.config 升级到 4.6 即可修复它,但我的任务是调查它。
这是根本错误:
System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
这就是代码,它在_client.PostAsync 处抛出,上面是 InnerException。 _client 是System.Net.Http.HttpClient
public async Task<CalculateResponse> Calculate(CalculateRequest request)
{
var env = new RequestEnvelope { Body = { RblsCalculate = request } };
request.LoginId = _username;
request.Password = _password;
var body = XmlConvert.SerializeObject(env);
var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
var httpResponse = await _client.PostAsync(_endpointPath, content);
var response = XmlConvert.ToObject<ResponseEnvelope>(await httpResponse.Content.ReadAsStreamAsync());
return response?.Body?.RblsCalculateResponse;
}
第三方没有进行任何更改,Windows 更新没有运行(这同时影响了 5 个不同的环境)。我们没有做任何改变。当我们部署时,我们每次都部署到一个新实例,服务器上的 web.config 没有更改,而之前的部署是几周前的。
我已经查看了对 4.6 的一些更改,如果不使用 TLSv1.0+ 作为协议,HttpClient 周围有一些潜在的重大更改,我已经在其中一台服务器上使用 Wireshark 进行了检查,我们正在使用 TLSv1。 2.但这并不能解释为什么它突然停止了。
更新 - 根据 @Trumpi 的建议从 trace.log 输出 SSL/TLS 跟踪
System.Net.Sockets Verbose: 0 : [16292] Data from Socket#52088480::PostCompletion
System.Net.Sockets Verbose: 0 : [16292] 00000000 : 16 03 01 00 88 01 00 00-84 03 01 58 A4 49 35 01 : ...........X.I5.
更新 2 - 删除了不必要的日志 ^^
【问题讨论】:
-
"当我使用 postman 或 curl 手动发布到第三方服务时,它响应良好。所以这是我们服务的问题 [...] 第三方没有制作任何更改” - 不同的是执行请求的时间。也许此时第三方服务超载,在升级过程中或其他任何情况下。如果运行 .NET 4.5.2 始终出现此错误而 .NET 4.6 没有,那么请检查两者之间 HTTP 标头的差异。
-
"被远程主机强制关闭"是从socket的错误一端调试问题。不知道为什么另一端决定放弃。跟着电线走。
-
@HansPassant 套接字的另一端是我无法访问的第 3 方应用程序。我确实联系了他们的支持团队,他们说他们看不到任何请求。
标签: c# .net owin dotnet-httpclient