我在使用 WEB Api 时遇到了一些性能问题。在我的真实/生产代码上,我将执行 SOAP WS 调用,在这个示例中,我只是 sleep 。我有 400 多个客户端向 Web API 发送请求。
我猜这是 web api 的问题,因为如果我打开 5 个进程,我可以处理比只有一个进程时更多的请求。
我的 Controller 测试异步版本看起来像这样
[HttpPost]
public Task<HttpResponseMessage> SampleRequest()
{
return Request.Content.ReadAsStringAsync()
.ContinueWith(content =>
{
Thread.Sleep(Timeout);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(content.Result, Encoding.UTF8, "text/plain")
};
});
}
同步版本是这样的
[HttpPost]
public HttpResponseMessage SampleRequest()
{
var content = Request.Content.ReadAsStringAsync().Result;
Thread.Sleep(Timeout);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(content, Encoding.UTF8, "text/plain")
};
}
此测试的客户端代码如下所示(配置为 30 秒后超时)
for (int i = 0; i < numberOfRequests; i++)
{
tasks.Add(new Task(() =>
{
MakeHttpPostRequest();
}));
}
foreach (var task in tasks)
{
task.Start();
}
我没能很好地把它放在这里,但是结果表可以在 github 找到。
CPU、内存和磁盘 IO 不足。始终至少有 800 个可用线程(工作线程和 io 线程)
public static void AvailableThreads()
{
int workerThreads;
int ioThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads);
Console.WriteLine("Available threads {0} ioThreads {1}", workerThreads, ioThreads);
}
我已经配置了 DefaultConnectionLimit
System.Net.ServicePointManager.DefaultConnectionLimit = Int32.MaxValue;
我的问题是为什么要排队回答这些请求? 在每次测试中,我的响应时间几乎与服务器 Thread.Sleep() 时间完全相同,但随着新请求到达,响应速度会变慢。
关于如何发现 Boot 在哪里的任何提示?
这是一个 .net 4.0 解决方案,使用自托管选项。
编辑:我还使用 .net 4.5 和 Web API 2.0 进行了测试,得到了相同的行为。 第一个请求几乎在 sleep 结束后立即得到答案,后来需要最多 4 倍的 sleep 时间才能得到答案。
编辑 2:Gist of the web api1 implementation和 gist of the web api2 implementation
Edit3:MakeHttpPost 方法创建一个新的 WebApiClient
编辑4:
如果我改变
Thread.Sleep()
到
await Task.Delay(10000);
在.net 4.5 版本中,它可以像预期的那样处理所有请求。所以我不认为与任何网络问题有关。 由于 Thread.Sleep() 会阻塞线程而 Task.Delay 不会,看来 webapi 存在消耗更多线程的问题?但是线程池中有可用的线程......
编辑 5:如果我打开 5 个服务器并将客户端数量加倍,服务器可以响应所有请求。所以看起来对服务器的请求数量不是问题,因为我可以“扩展”这个在不同端口运行大量进程的解决方案。更多的是同一个进程的请求数量问题。
最佳答案
如何检查 TCP/IP 堆栈是否过载
在有问题的服务器上运行 Netstat,查找任何时间等待、Fin-Wait-1、Fin-Wait-2 和 RST-Wait、RST-Wait2。这些是半生不熟的 session ,堆栈正在等待另一端清理......或者......另一端确实发送了一个数据包,但本地机器还不能处理它们,这取决于堆栈' 完成工作的可用性。
问题在于,即使 session 显示 Established 也可能会遇到麻烦,因为超时尚未触发。
上述症状让人联想到网络或 TCP/IP 堆栈过载。当路由器过载时,会出现非常相似的行为。
关于c# - Web API 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32485985/