如何防止插座/端口耗尽? [英] How do I prevent Socket/Port Exhaustion?

查看:211
本文介绍了如何防止插座/端口耗尽?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用多个线程请求击中它试图性能测试网站。每个线程执行的 N 的时间。 (在for循环中)



不过,我遇到了问题。特别是引发WebException(无法连接到远程服务器)的内部异常:




套接字上的操作不能因为执行该系统
缺少足够的缓冲区空间,或因为队列满
127.0.0.1:52395




我试图在每个线程500次迭代运行100个线程。



起初我是用的HttpWebRequest 在System.Net使GET请求到服务器。目前我使用 Web客户端,因为我认为每个迭代使用一个新的socket(在很短的时间内使100 * 500插座)。我以为Web客户端(被实例化每个线程一次)也只使用一个插座。



我不需要50万用插座同时打开,因为我想发送GET请求,接收响应,并关闭套接字,释放它使用在接下来的循环迭代。据我所知,这将是



问题

然而,即使使用Web客户端,被请求一堆插座都导致了一堆插座的 TIME_WAIT 模式(用netstat选中)。这将导致其他应用程序(如Internet浏览器)挂起,并停止工作。



我可以用更少的迭代和/或更少的线程运行我的测试,因为它出现的插座做最终退出TIME_WAIT状态。然而,这不是因为它不充分测试Web服务器的能力的溶液



<强>问题:



我如何明确每个线程迭代后,为了防止TIME_WAIT状态和插座疲惫?



关闭套接字(从客户端)

代码:



类封装了的HttpRequest



编辑的使用并设置为每次迭代中使用裹WebClient的,所以一个新的被实例化。但问题依然存在。



 公共密封类HttpGetTest:ITEST {
私人只读字符串m_url;

公共HttpGetTest(字符串URL){
m_url =网址;
}

无效ITest.Execute(){使用
(Web客户端Web客户端=新的WebClient()){使用(流流= webClient.OpenRead(m_url
) ){
}
}
}
}

我ThreadWrapperClass的创建一个新的线程部分:

 公共无效执行(){
行动锤=( )= GT; {
的for(int i = 1; I< = m_iterations;我++){
//如果m_test是一种通过ITEST构造
m_test.Execute注射();
}
};
工作的ThreadStart委托= {
锤();
};
线程线程=新主题(主持工作);
thread.Start();
}


解决方案

你明白的目的时间的等待?这是一个时期,它是不安全的重新使用端口,因为丢失的数据包(已成功重传)从以前的事务可能还没有在该期限内交付。



你很可能调整下来在注册表中的某个地方,但我怀疑这是否是一个明智的下一个步骤。



我在测试环境中创建实际负载的经验已经证明非常令人沮丧。当然,运行从本地主机的负载测试仪绝不是现实的,也是最网络测试我已经使用.NET HTTP API的似乎都需要在客户端比服务器本身更咕噜咕噜的。



因此,它是更好地移动到第二台机器为您的服务器上生成负载。然而国内的路由设备很少达到的任何地方配套近连接数的工作会导致任何类型的负载一个写得很好的服务器应用程序,所以现在你需要升级你的路由/交换设备,以及!



最后,我有过身边的一些非常奇怪的和意想不到的性能问题在.NET http客户端API。在一天结束的时候,他们都使用的HttpWebRequest做繁重。国际海事组织它远不及高性能的,因为它可以。 DNS是采用同步,异步调用这些API,即使(尽管如果你只从单一的主机请求,这是不是一个问题),并持续使用CPU使用率小兵后,直到客户端成为制约CPU,而不是IO限制。如果你正在寻找创造持续,重负荷,任何请求重型应用上的HttpWebRequest依赖是国际海事组织一个虚假的投资。



所有的一切,一个非常棘手的工作,以及最终的东西,只能在野外证明,除非你有现金花在更好的装备的舰队plently



[提示:我有从我自己的客户更好的使用性能比较异步的Socket API和第三方DNS客户端库编写]


I am attempting to performance test a website by hitting it with requests across multiple threads. Each thread executes n times. (in a for loop)

However, I am running into problems. Specifically the WebException ("Unable to connect to remote server") with the inner exception:

An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full 127.0.0.1:52395

I am attempting to run 100 threads at 500 iterations per thread.

Initially I was using HttpWebRequest in System.Net to make the GET request to the server. Currently I am using WebClient as I assumed that each iteration was using a new socket (so 100 * 500 sockets in a short period of time). I assumed WebClient (which is instantiated once per thread) would only use one socket.

I don't need 50 000 sockets open at once, as I would like to send the GET request, receive the response, and close the socket, freeing it for use in the next loop iteration. I understand that it would be a problem to

However, even with WebClient, a bunch of sockets are being requested resulting in a bunch of sockets in TIME_WAIT mode (checked using netstat). This causes other applications (like internet browsers) to hang and stop functioning.

I can operate my test with less iterations and/or less threads, as it appears the sockets do eventually exit this TIME_WAIT state. However, this is not a solution as it doesn't adequately test the abilities of the web server.

Question:

How do I explicitly close a socket (from the client side) after each thread iteration in order to prevent TIME_WAIT states and socket exhaustion?

Code:

Class that wraps the HttpRequest

Edit: Wrapped WebClient in a using, so a new one is instantiated,used and disposed for every iteration. The problem still persists.

  public sealed class HttpGetTest : ITest {
    private readonly string m_url;

    public HttpGetTest( string url ) {          
        m_url = url;
    }

    void ITest.Execute() {
        using (WebClient webClient = new WebClient()){
            using( Stream stream = webClient.OpenRead( m_url ) ) {          
            }
        }
    }
}

The part of my ThreadWrapperClass that creates a new thread:

public void Execute() {
    Action Hammer = () => {
        for( int i = 1; i <= m_iterations; i++ ) {
            //Where m_test is an ITest injected through constructor
            m_test.Execute();
        }       
    };
    ThreadStart work = delegate {
        Hammer();
    };
    Thread thread = new Thread( work );
    thread.Start();
}

解决方案

Do you understand the purpose of TIME_WAIT? It's a period during which it would be unsafe to reuse the port because lost packets (that have been successfully retransmitted) from the previous transaction might yet be delivered within that time period.

You could probably tweak it down in the registry somewhere, but I question if this is a sensible next step.

My experience of creating realistic load in a test environment have proved very frustrating. Certainly running your load-tester from localhost is by no means realistic, and most network tests I have made using the .net http apis seem to require more grunt in the client than the server itself.

As such, it's better to move to a second machine for generating load on your server... however domestic routing equipment is rarely up to the job of supporting anywhere near the number of connections that would cause any sort of load on a well written server app, so now you need to upgrade your routing/switching equipment as well!

Lastly, I've had some really strange and unexpected performance issues around the .net Http client API. At the end of the day, they all use HttpWebRequest to do the heavy lifting. IMO it's nowhere near as performant as it could be. DNS is sychronous, even when calling the APIs asynchronously (although if you're only requesting from a single host, this isn't an issue), and after sustained usage CPU usage creeps up until the client becomes CPU constrained rather than IO constrained. If you're looking to generate sustained and heavy load, any request-heavy app reliant on HttpWebRequest is IMO a bogus investment.

All in all, a pretty tricky job, and ultimately, something that can only be proved in the wild, unless you've got plently of cash to spend on an armada of better equipment.

[Hint: I got much better perfomance from my own client written using async Socket apis and a 3rd party DNS client library]

这篇关于如何防止插座/端口耗尽?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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