我正在尝试衡量网络服务的吞吐量。
为了做到这一点,我编写了一个小工具,可以连续发送请求并从多个线程中读取响应。
每个线程的内部循环的内容如下所示:
public void PerformRequest()
{
WebRequest webRequest = WebRequest.Create(_uri);
webRequest.ContentType = "application/ocsp-request";
webRequest.Method = "POST";
webRequest.Credentials = _credentials;
webRequest.ContentLength = _request.Length;
((HttpWebRequest)webRequest).KeepAlive = false;
using (Stream st = webRequest.GetRequestStream())
st.Write(_request, 0, _request.Length);
using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse())
using (Stream responseStream = httpWebResponse.GetResponseStream())
using (BufferedStream bufferedStream = new BufferedStream(responseStream))
using (BinaryReader reader = new BinaryReader(bufferedStream))
{
if (httpWebResponse.StatusCode != HttpStatusCode.OK)
throw new WebException("Got response status code: " + httpWebResponse.StatusCode);
byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength);
httpWebResponse.Close();
}
}
似乎工作正常,除了某些东西似乎限制了这个工具。如果我使用每40个线程运行该工具的两个实例,那么我获得的吞吐量明显高于具有80个线程的一个实例。
我找到了ServicePointManager.DefaultConnectionLimit属性,我设置为10000(如果我通过app.config as suggested by Jader Dias设置它没有区别。)
在.NET或我的机器上是否有任何其他可能影响性能的设置? (我正在运行Vista,但我在Windows Server 2003上看到了同样的问题)。
或许对单个进程可以建立多少连接有一些限制?
答案 0 :(得分:37)
您必须在app.config或web.config文件中设置maxconnection参数:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="80"/>
</connectionManagement>
</system.net>
</configuration>
在Windows XP中,高达100的值可以很好地工作。
更新:我刚刚发现上面的方法是另一种设置System.Net.ServicePointManager.DefaultConnectionLimit的方法
答案 1 :(得分:2)
答案 2 :(得分:2)
您是否尝试过增加网络设置中的最大连接数?
答案 3 :(得分:1)
请记住,多线程代码总是会导致对任何共享资源的争用,即使您没有明确地共享任何可能正在使用共享资源的类的内容。
如果你真的用2 40个线程exes而不是1 80个线程exe获得更好的性能,那么你需要用共享资源开始调查。如果是这种情况,您引用的代码远没有创建和管理线程的代码那么有趣。
我要抛弃的另一件事是,你可以获得一些工具,这些工具一般会为你做这类事。见http://support.microsoft.com/kb/231282。 Visual Studio中也包含(我不确定是什么skus)是新一代Web应用程序性能测试工具。我相信如果你看起来你也可以找到一些非MS的东西。
答案 4 :(得分:0)
w.r.t表现有两个重要方面:
一方面是所有人建议的,客户端使用数量的TCP连接 (通常更好,如果这些连接被持久化(keep alive = true)),请参阅:http://msdn.microsoft.com/en-us/library/system.net.servicepoint.connectionlimit(v=vs.110).aspx,How and where the TCP connection has been created in httpwebrequest, and how is it related to servicepoint?,Why System.Net.ServicePoint.ConnectionLimit uses '7FFFFFFF' (Int32.MaxValue/2147483647) when a client connects to a service on 'localhost'?,System.Net.ServicePointManager.DefaultConnectionLimit and .MaxServicePointIdleTime)
第二个方面不是使用多个新线程/或使用工作线程在代码片段中使用同步调用(如httpwebrequest.getrequeststream)并行工作,完全拥抱异步模型 (例如,开始/结束请求流或新任务变体)。这样CPU总是很忙,让I / O完成端口线程只需通过调用回调在工作线程池线程中发送响应。 (您可以参考:How does .NET make use of IO Threads or IO Completion Ports?,http://blog.marcgravell.com/2009/02/async-without-pain.html,HttpWebRequest and I/O completion ports)
的问候。
答案 5 :(得分:-1)
你是如何创建线程的?我假设你知道你有80个线程,你没有使用线程池管理器,因为使用线程池管理器你可以要求尽可能多的线程,你一次只能获得25个活动线程。如果使用数组手动创建线程,那么实际上您将获得所需数量,但是它们仍然位于相同的进程空间中,因此可能会限制它们在单独进程中运行的线程。
您还可以查看线程创建的公寓样式,我相信Thread类ctor默认使用STA。尝试使用MTA,看看它们是否会影响性能。