c# - Web API 的性能

标签 c# .net performance asp.net-web-api

我在使用 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 implementationgist 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/

相关文章:

.net - 我的Visual Studio中缺少.NET Core 2.0

c# - CA1701/自定义词典

iphone - 在 Xcode/Iphone 中测量 FPS/性能

c# - 只读 Dictionary<int, List<int>>

c# - 项目中不存在目标 "PreComputeCompileTypeScript"

c# - 在 C# 中使用大量 COM 对象的内存使用过多

c# - 如何在自己的代码中模仿(单参数)重载决议规则?

c++ - 更正我的次优二进制搜索

Mysql 8列索引

c# - Selenium 网络驱动程序 : Specify filepath for Firefox exe