Raf*_*ler 8 .net c# performance asp.net-web-api
我在使用WEB Api时遇到了一些性能问题.在我的真实/生产代码上,我将做一个SOAP WS调用,在这个示例中,我只是睡觉.我有400多个客户端向Web API发送请求.
我想这是web api的一个问题,因为如果我打开5个进程,我可以处理更多的请求,而不是只有一个进程.
我的控制器的测试异步版本看起来像这样
[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")
};
});
}
Run Code Online (Sandbox Code Playgroud)
同步版本看起来像这样
[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")
};
}
Run Code Online (Sandbox Code Playgroud)
我对此测试的客户端代码看起来像这样(它被配置为在30秒后超时)
for (int i = 0; i < numberOfRequests; i++)
{
tasks.Add(new Task(() =>
{
MakeHttpPostRequest();
}));
}
foreach (var task in tasks)
{
task.Start();
}
Run Code Online (Sandbox Code Playgroud)
我无法以一种很好的方式将它放在这里,但结果表可以在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);
}
Run Code Online (Sandbox Code Playgroud)
我已经配置了DefaultConnectionLimit
System.Net.ServicePointManager.DefaultConnectionLimit = Int32.MaxValue;
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么有一个队列来回答这些请求?在每次测试中,我的响应时间几乎与服务器Thread.Sleep()时间完全相同,但响应在新请求到达时变慢.
关于如何发现bootleneck的任何提示?
它是一个.net 4.0解决方案,使用自托管选项.
编辑:我还测试了.net 4.5和Web API 2.0,并得到了相同的行为.第一次请求几乎在睡眠过期后得到答案,之后需要4倍的睡眠时间才能得到答案.
EDIT2:网络API1实施的要点和主旨的网站API2实施
Edit3:MakeHttpPost方法创建一个新的WebApiClient
Edit4:
如果我改变了
Thread.Sleep()
Run Code Online (Sandbox Code Playgroud)
至
await Task.Delay(10000);
Run Code Online (Sandbox Code Playgroud)
在.net 4.5版本中,它可以按预期处理所有请求.所以我不认为与任何网络问题有关的事情.由于Thread.Sleep()阻塞线程而Task.Delay没有,看起来webapi有一个问题是消耗更多的线程?但是线程池中有可用的线程......
编辑5:如果我打开5台服务器并将客户端数量增加一倍,则服务器可以响应所有请求.所以看起来对服务器的请求数量不是问题,因为我可以"扩展"这个解决方案在不同的端口运行大量进程.对同一进程的请求数量来说,这更是一个问题.
在有问题的服务器上运行 Netstat,查找任何 Time-Wait、Fin-Wait-1、Fin-Wait-2 和 RST-Wait、RST-Wait2。这些是半生不熟的会话,堆栈正在等待另一端清理......或者......另一端确实发送了一个数据包,但本地计算机尚无法处理它们,具体取决于堆栈' 能够完成这项工作。
更糟糕的是,即使显示“已建立”的会话也可能会遇到麻烦,因为暂停尚未触发。
上述症状让人想起网络或 TCP/IP 堆栈过载。当路由器过载时,会出现非常相似的行为。
| 归档时间: |
|
| 查看次数: |
978 次 |
| 最近记录: |