标杆ASP.NET并发请求效果差 [英] Benchmarking ASP.NET concurrent requests poor results

查看:109
本文介绍了标杆ASP.NET并发请求效果差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code,我的基准使用JMeter和我的本地机器上得到每秒约3000请求(等待缺少故意同步运行)

 公共异步任务< Htt的presponseMessage>得到()
{
    VAR RESP =新的Htt presponseMessage(的HTTPStatus code.OK);
    resp.Content =新的StringContent(Thread.CurrentThread.ManagedThreadId.ToString(),Encoding.UTF8,text / plain的);
    返回RESP;
}

的问题是,当我暂停像下面的一个第二请求,由于某种原因,吞吐量下降到每秒10个请求的每个w3wp.exe进程(再次 AWAIT 缺少有意同步运行):

 公共异步任务< Htt的presponseMessage>得到()
    {
        Task.Delay(1000).Wait();
        VAR RESP =新的Htt presponseMessage(的HTTPStatus code.OK);
        resp.Content =新的StringContent(Thread.CurrentThread.ManagedThreadId.ToString(),Encoding.UTF8,text / plain的);
        返回RESP;
    }

甚至当我使用的await 没有区别和每秒10个请求根本不改善:

 公共异步任务< Htt的presponseMessage>得到()
{
    等待Task.Delay(1000);
    VAR RESP =新的Htt presponseMessage(的HTTPStatus code.OK);
    resp.Content =新的StringContent(Thread.CurrentThread.ManagedThreadId.ToString(),Encoding.UTF8,text / plain的);
    返回RESP;
}

我尝试了所有的配置设置,并没有作出任何变化都:
`


  

的web.config


 < system.net>
    < connectionManagement>
      <添加地址=*MAXCONNECTION =65400/>
    < / connectionManagement>
  < /system.net>


  

aspnet.config


 <&的System.Web GT;
    < applicationPool
        maxConcurrentThreadsPerCPU =100/>
  < /system.web>


  

machine.config中


 <中processModel
 AUTOCONFIG =假
 的memoryLimit =70
 maxWorkerThreads =100
 maxIoThreads =100/>

该CONFIGS被设置为x86和x64

我的MEM 32演唱会和4个物理核心的Windows 10。

钳工每秒10请求时,CPU不超过10%的负载去了。

以上code使用Web API,但我当然使用HTTP处理程序重现相同的结果。


解决方案

下面是一个可能的理解。一调查,无论如何。

Task.Delay()创建一个新的任务,其工作是暂停。如果我理解正确,任务常常会派遣到.NET工作池,其中有一个规模有限。 (你可以用<一个href=\"https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads(v=vs.110).aspx\"相对=nofollow> ThreadPool.GetMaxThreads 中)当你试图把太多,code将'备份',因为它会等待线程池有空间。

因此​​,让我们说你有大小40的线程池一旦你已经派出40的任务,都在等待第二个,你最大程度的发挥线程池。您的瓶颈将是任务,脱胶了线程池,没有产生空间。

通常情况下,做昂贵的IO如数据库查询或文件IO良率的控制,而他们等待要做的工作任务。我不知道如果Task.Delay更粘人。

尝试更换Task.Delay()为System.Threading.Thread.Sleep(),看看是否改变任何东西。

I have the following code that I benchmark with jMeter and get about 3000 request per second on my localhost machine(the await is missing intentionally to run synchronously):

public async Task<HttpResponseMessage> Get()
{
    var resp = new HttpResponseMessage(HttpStatusCode.OK);
    resp.Content = new StringContent(Thread.CurrentThread.ManagedThreadId.ToString(), Encoding.UTF8, "text/plain");
    return resp;
}

The problem is that when I pause the request for one second like below, for some reason the throughput is down to 10 requests per second for each w3wp.exe process (again the await is missing intentionally to run synchronously):

public async Task<HttpResponseMessage> Get()
    {
        Task.Delay(1000).Wait();
        var resp = new HttpResponseMessage(HttpStatusCode.OK);
        resp.Content = new StringContent(Thread.CurrentThread.ManagedThreadId.ToString(), Encoding.UTF8, "text/plain");
        return resp;
    }

Even when I do use await there is no difference and the 10 requests per second does not improve at all:

public async Task<HttpResponseMessage> Get()
{
    await Task.Delay(1000);
    var resp = new HttpResponseMessage(HttpStatusCode.OK);
    resp.Content = new StringContent(Thread.CurrentThread.ManagedThreadId.ToString(), Encoding.UTF8, "text/plain");
    return resp;
}

I tried all the config settings and nothing makes any change at all: `

web.config

  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="65400" />
    </connectionManagement>
  </system.net>

aspnet.config

  <system.web>
    <applicationPool 
        maxConcurrentThreadsPerCPU="100" />
  </system.web>

machine.config

 <processModel
 autoConfig="false"
 memoryLimit="70"
 maxWorkerThreads="100"
 maxIoThreads="100" />

The configs are set for both x86 and x64

I have 32 gigs of mem and 4 physical cores, Windows 10.

The CPU doesn't go over 10% load when benching the 10 requests per second.

The above code uses WEB API, but of course I reproduce the same results using a HTTP Handler.

解决方案

Here's a possible understanding. One to investigate, anyway.

Task.Delay() creates a new task, whose job is to pause. If I understand right, tasks often get dispatched to the .Net worker pool, which has a limited size. (You can check with ThreadPool.GetMaxThreads) When you try to put too much in, code will 'back up' as it waits for the thread pool to have space.

So let's say you have a thread pool of size 40. Once you've dispatched 40 tasks, all waiting a second, you max out the thread pool. Your bottleneck would be the tasks, gumming up the thread pool, not yielding space.

Normally, tasks that do expensive IO like database queries or file IO yield control while they wait for the work to be done. I wonder if Task.Delay is more 'clingy'.

Try swapping Task.Delay() for System.Threading.Thread.Sleep() and see if that changes anything.

这篇关于标杆ASP.NET并发请求效果差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆