【发布时间】:2019-12-23 19:14:33
【问题描述】:
我使用以下代码对运行在 IIS 服务器上的远程 ASP .Net WebApi 执行 HTTP GET 请求。该请求返回一个大小约为 5 兆字节的 JSON 对象。几乎所有时间,这个请求都成功了,我得到了正确的 JSON 响应,但是(大约 2-3% 的时间,随机分布)我在响应正文中得到了一个不完整的 JSON。响应代码为 200 OK,但 JSON 数据在随机位置被截断。 在 Fiddler 中,我确实看到响应 JSON 在随机位置被剪切,所以看起来服务器出于某种原因正在关闭中间的连接。
我在其他 SO 线程中读到,迁移到 HTTP V1.0 或将 Connection 标头设置为“关闭”可能会解决问题,但它对我没有用。这是我在这里缺少的 IIS 服务器设置吗?还是客户端配置错误?
在来自相同 api 的其他路由上使用相同代码时,该问题似乎不会重现,返回的 JSON 响应要小得多(小于 1 兆字节)。
还需要注意的是,我们的客户端和 IIS 服务器(Incapsula)之间有一些负载平衡器机制。此负载均衡器还提供 DDos 预防。
这是我的 C# 代码(我使用的是最新的 HttpClient 版本):
using (var httpClient = new HttpClient())
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("https://api-real.bgtm.com/Orders"));
using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
{
InstResponse s = httpResponseMessage.Content.ReadAsAsync<InstResponse>().GetAwaiter().GetResult();
Console.Write("Finished without error.");
}
}
这是我在尝试从响应流中读取不完整的 JSON 时得到的完整异常详细信息:
{System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The server returned an invalid or unrecognized response.
at System.Net.Http.HttpConnection.FillAsync()
at System.Net.Http.HttpConnection.CopyToExactLengthAsync(Stream destination, UInt64 length, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.ContentLengthReadStream.CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.HttpConnectionResponseContent.SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken)
at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)
--- End of inner exception stack trace ---
at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at ConsoleApp1.Program.MainAsync ()}
我还可以添加来自 WireShark 的屏幕截图,显示服务器是第一个发送 FIN 消息的服务器。服务器 IP 为 107.154.192.59,客户端 IP 为 10.10.80.146:ScreenShot
非常绝望,有人见过这种不一致的行为吗?
谢谢
【问题讨论】:
-
这可能有关系,也可能没有关系,但你应该看看这篇关于套接字耗尽的文章:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
-
200 响应不完整主要是异步任务造成的。如果是 IIS 错误,您可能会重现此问题。响应不完整的 200 显示异步任务异常。你有没有注意到,当你得到不完整的 json 时,完成请求需要多长时间。
-
不完整的JSON请求似乎需要更长的时间:成功的请求大约需要1秒,不成功的大约需要4秒。
-
听起来应用程序达到了一些缓冲区限制。您是否尝试过更改某些 httpruntime 或服务器运行时配置并监控其影响?
标签: c# asp.net json iis httpclient