最大并发HttpWeb请求数量

67

我正在对一个Web应用进行压力测试,已经设置了一个Windows测试程序,启动了多个线程,并在每个线程上发送一个Web请求。

问题是我得到了以下输出:

01/09/09 11:34:04 Starting new HTTP request on 10
01/09/09 11:34:04 Starting new HTTP request on 11
01/09/09 11:34:04 Starting new HTTP request on 13
01/09/09 11:34:05 Starting new HTTP request on 14
01/09/09 11:34:05 Starting new HTTP request on 11
01/09/09 11:34:05 11 has finished!
01/09/09 11:34:05 Starting new HTTP request on 13
01/09/09 11:34:05 13 has finished!
01/09/09 11:34:05 Starting new HTTP request on 14
01/09/09 11:34:05 14 has finished!
01/09/09 11:34:05 Starting new HTTP request on 11
01/09/09 11:34:05 11 has finished!
01/09/09 11:34:05 Starting new HTTP request on 14
01/09/09 11:34:05 14 has finished!
01/09/09 11:34:05 Starting new HTTP request on 13
01/09/09 11:34:05 13 has finished!
01/09/09 11:34:05 Starting new HTTP request on 15
01/09/09 11:34:06 Starting new HTTP request on 11
01/09/09 11:34:06 11 has finished!
01/09/09 11:34:06 Starting new HTTP request on 14
01/09/09 11:34:06 14 has finished!

尽管我这样创建了100个线程,但情况看起来最多只会有5个线程:

int numberOfThreads = Convert.ToInt32(txtConcurrentThreads.Text);

    List<BackgroundWorker> workers = new List<BackgroundWorker>();

    for (int N = 0; N < numberOfThreads; N++)
    {

        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        workers.Add(worker);
    }


    foreach(BackgroundWorker worker in workers)
    {
        worker.RunWorkerAsync();
    }

有人能启发我一下到底发生了什么吗?

谢谢

编辑:如果像建议的那样睡眠5秒钟,而不是使用httpwebrequest,那么我确实会有更多的线程触发,但并不像我所预期的那么多:

01/09/09 11:56:14 Starting new HTTP request on 7
01/09/09 11:56:14 Starting new HTTP request on 11
01/09/09 11:56:15 Starting new HTTP request on 12
01/09/09 11:56:15 Starting new HTTP request on 13
01/09/09 11:56:16 Starting new HTTP request on 14
01/09/09 11:56:16 Starting new HTTP request on 15
01/09/09 11:56:17 Starting new HTTP request on 16
01/09/09 11:56:17 Starting new HTTP request on 17
01/09/09 11:56:18 Starting new HTTP request on 18
01/09/09 11:56:19 Starting new HTTP request on 7
01/09/09 11:56:19 7 has finished!
01/09/09 11:56:19 Starting new HTTP request on 11
01/09/09 11:56:19 11 has finished!
01/09/09 11:56:19 Starting new HTTP request on 19
01/09/09 11:56:20 Starting new HTTP request on 20
01/09/09 11:56:20 Starting new HTTP request on 12
01/09/09 11:56:20 12 has finished!

看起来每秒只有两个线程启动,这对我来说速度非常慢。我想Console.WriteLine可能是个问题吗?

编辑:我设置了

ThreadPool.SetMinThreads(100, 4); 
并且
System.Net.ServicePointManager.DefaultConnectionLimit = 100;

并且得到了以下结果:

01/09/09 14:00:07 Starting new HTTP request on 11
01/09/09 14:00:07 Starting new HTTP request on 81
01/09/09 14:00:07 Starting new HTTP request on 82
01/09/09 14:00:07 Starting new HTTP request on 79
01/09/09 14:00:07 Starting new HTTP request on 83
01/09/09 14:00:07 Starting new HTTP request on 84
01/09/09 14:00:07 Starting new HTTP request on 85
01/09/09 14:00:07 Starting new HTTP request on 87
01/09/09 14:00:07 Starting new HTTP request on 88
...
01/09/09 14:00:07 84 has finished! Took 323.0323 milliseconds
01/09/09 14:00:08 88 has finished! Took 808.0808 milliseconds
01/09/09 14:00:08 96 has finished! Took 806.0806 milliseconds
01/09/09 14:00:08 94 has finished! Took 806.0806 milliseconds
01/09/09 14:00:08 98 has finished! Took 801.0801 milliseconds
01/09/09 14:00:08 80 has finished! Took 799.0799 milliseconds
01/09/09 14:00:08 86 has finished! Took 799.0799 milliseconds
01/09/09 14:00:08 92 has finished! Took 799.0799 milliseconds
01/09/09 14:00:08 100 has finished! Took 812.0812 milliseconds
01/09/09 14:00:08 82 has finished! Took 1010.101 milliseconds

我能同时发出大量的Web请求,但它们似乎被排队了(调用STA COM+服务器),这就是我预期的。

感谢您的帮助。


1
我对你的解决方案有一个问题。根据 MSDN(https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit(v=vs.110).aspx),默认值是 max int32,比你在这里设置的 100 要大得多。即使您没有将其设置为 100,它也会有什么区别?我的意思是,我有点怀疑您是通过设置 ServicePointManager 的默认连接限制还是通过设置第一个答案中的 connectionManagement 元素来解决它。 - foxwendy
1
@foxwendy,MSDN上说是int.MaxValue,但我在.NET 4.5中尝试时,默认值只有2。 - xmedeko
4个回答

76

你的请求是不是大部分都发送到同一个主机?因为系统会对每个主机设置一个内置的请求上限。你可以在 app.config 的 system.Net connectionManagement 元素中更改这个上限。

另一件事是,线程池只会逐渐增加其线程数量 - 据我所知,它每半秒钟启动一个新线程。这可能就是你看到的情况吧?试试将 HttpWebRequest 从方程式中移除 - 只需睡眠几秒钟即可......

我怀疑你最初遇到的问题是后者,但前者也会给你带来麻烦。


是的,它们都将连接到本地主机。 - Duncan
我不确定这个限制是否适用于本地主机...但这绝对是需要注意的事情。请查看我的编辑,其中包含了app.config元素的链接。 - Jon Skeet
1
这个限制是否适用于使用HTTP绑定向WCF服务发出请求的WCF客户端?我的假设是肯定的...? - John B
此外,看起来有一个Windows注册表设置WinInet的“MaxConnectionsPerServer”,默认为HTTP 1.1服务器的2个连接。这个web.config设置会覆盖它吗?还是我仍然需要提高注册表设置呢? - John B
1
Windows注册表设置仅适用于WinINET;.NET会忽略它。 - EricLaw
天啊,谢谢你!我的一个应用程序可以并行下载一堆报告。我已经解决了所有并发问题和所有数据库连接,但是当规模扩大时它仍然运行得比应该慢得多。这就是问题所在。谢谢!谢谢!谢谢! - Sam

57

7
如有疑问,此设置的默认值为2。 - July.Tech

14

关于.NET Core的这个问题我还没有听说过很多。 ServicePointManager在.NET Core 1中没有包含,但似乎在版本2中又回来了。然而,对于HttpClient,您也可以像这样设置最大连接数:

new HttpClient(new HttpClientHandler
                {
                    MaxConnectionsPerServer = 100
                })

7
如果我在Windows配置中写入下面的标签,那么每次执行下面的代码时,它都会被执行。因此,每次执行下面的代码时,我将被允许最多有1000000个并行请求/响应。
HttpWebRequest POSTRequest = (HttpWebRequest)WebRequest.Create("http://yahoo.com");

标签

<connectionManagement>
 <clear/>
 <add address="*" maxconnection="1000000" />
</connectionManagement>

我可以确认上述更改在App.config中允许多个HttpWebRequests发生。即,将maxconnection="<integer>"放置其中。 - Vinnie Amir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接