我正在开发一个工具来在UDP服务器上执行负载测试(使用在NT 6.x上运行的C#/。NET 4.0,尽管这不太相关)。服务器与数万个客户端进行通信,每个客户端之间的通信流量非常低且不经常。所有通信都遵循请求 - 回复模式,其中一方开始与另一方进行通信,然后另一方回复。当服务器需要向客户端发送内容时,他查找客户端的最后一个已知端点(IP +端口)并发送UDP数据包,并在单个已知端口上侦听回复,该端口用于接收来自所有端口的通信客户端。当客户端启动通信时,它已经知道服务器的端点,并且只是从临时端口发送数据包并等待同一端口上的回复。相同的短暂端口用于客户端的生命周期。
负载测试工具的设计非常简单;模仿每个客户的行为,状态和决策,以低而充足的复杂性。由于与每个客户端的通信只是偶然的(每隔几秒),并且每次通信所需的处理量非常小,我能想到的最佳方法是使用单个线程和单个套接字来执行所有通信对于大量模拟客户端,很可能仍然不会使线程完全忙并且套接字饱和。不幸的是,由于每个客户端从他自己的端口发送和接收这一事实,我遇到了两个问题:
以上两个约束似乎意味着我必须为每个客户端创建一个套接字,因为UDP数据包必须来自某个端口,并且回复将被发送到该端口。所以第一个可能的解决方案就是这样做,为每个模拟客户端创建一个套接字。假设我们在一台机器上模拟30,000个客户端:
另一种方法是使用单个套接字,但我之前提到的两个问题必须首先以某种方式解决:
还有其他方法我没想过吗?我走错了路吗?你能想到更好的解决方案吗?我很乐意听到你的任何建议。
答案 0 :(得分:4)
是的,您可以轻松创建> Windows机器上有30,000个套接字,但您可能需要调整MAXUSERPORT
(请参阅here)。
使用I / O完成端口或异步I / O,然后您不必担心“轮询”并且可扩展性“正常”。
主要的资源问题是非页面缓冲池,但这在Vista或更高版本上已经不那么重要了(参见here),下一个问题是I / O锁定页面限制可能是个问题如果你为你的读取发布非常大的缓冲区,但鉴于这是UDP,我假设你将拥有'合理'大小的数据报,因此锁定的页面限制不太可能是一个问题。
我在这里写了一些关于可扩展性问题的博客:http://www.serverframework.com/asynchronousevents/2010/12/one-million-tcp-connections.html
我使用C++ socket server framework编写了类似于您尝试执行的工具。有一个UDP测试工具示例作为框架的一部分提供,它从唯一的客户端端口发送可配置数量的数据报并等待回复,并且易于调整以处理您的特定数据报格式和响应要求(请参阅{{3} })。