保持 140 个 TCP 连接?
Posted
技术标签:
【中文标题】保持 140 个 TCP 连接?【英文标题】:Persisting 140 TCP connections? 【发布时间】:2011-11-02 10:25:41 【问题描述】:我们目前正在研究在 .NET Micro 框架上运行的 120-140 个嵌入式硬件设备与服务器之间进行通信的最有效方式。
每个嵌入式设备都需要通过 TCP 实时地定期向服务器发送和请求信息。
我的问题是:最好初始化 140 个与服务器的 TCP 连接,然后挂起这些连接,还是为设备的每个请求初始化一个新连接?保持和管理 140 个 TCP 连接会给服务器带来很大压力吗?
当服务器在数据库中检测到新数据时,它需要将此新信息发送到 1..* 设备(信息针对特定设备),如果我保持 140 个连接,我需要查找每次我需要发送信息而不是仅仅发送到与新数据相关联的 IP:PORT 时,正确的连接。
我猜另一个可能很愚蠢的问题是,是否真的有可能在单个端口上挂起 140 个 TCP 连接?
感谢任何建议/cmets!
【问题讨论】:
您是否考虑过为低带宽网络和处理资源有限的设备设计的现有解决方案,例如 MQTT-S 或 CoAP? 不是真的,会调查这个,谢谢你的评论。 【参考方案1】:一般而言,您最好尽可能长时间地保持连接。如果您让每个设备在每次发送消息时都打开一个连接,那么您最终可以有效地对服务器进行 DoS,因为它最终会导致大量处于 TIME_WAIT 状态的套接字占用其表中的空间。
我在一个系统上工作,其中有一堆客户端与服务器通信,虽然它们可以定期打开和关闭,但最好保持连接(并在连接断开时重新建立连接,并且需要发送新消息)。您最终可能需要编写稍微复杂一些的代码,但我发现为减少服务器负载付出努力是值得的。
现代操作系统的缓冲区可能比我实际遇到 DoS 影响的缓冲区更大,但使用大量这样的连接从根本上说不是最好的主意。
客户端的情况可能会变得相对复杂,尤其是当设备倾向于对应用程序透明地进入睡眠状态时,因为这意味着连接会在应用程序认为它们仍处于打开状态时超时。当我们这样做时,我们最终得到了相对复杂的网络代码,因为我们需要处理这样一个事实,即套接字可能(并且会)理所当然地失败,我们只需要建立一个新的连接并重新尝试发送消息.您只需将此代码放入您的库中,一旦完成就忘记它。
实际上,在实践中,我们的初始应用程序的代码甚至更复杂,因为它正在处理一个半感知设备停止启动性质并试图重新发送失败消息的网络库,有时意味着相同的消息被发送了两次。我们最终在顶部做了一层额外的沟通,以确保重复被拒绝。如果您使用的是 C# 或常规 BSD 样式的套接字,尽管我猜您不应该有这个问题。这是一个管理重新连接的专有库,但在重新发送时会让人头疼,而且它的默认超时是不适当的。
【讨论】:
感谢您的评论,我认为我们倾向于这种方法,我们只是担心如果我们确实保持连接打开,可能会给客户端(嵌入式设备)带来压力。初始化连接的客户端是否必须做很多事情才能使其保持打开状态,还是服务器会处理这个问题? @Adrian 我已经扩展了我的答案,希望能回答你的问题。【参考方案2】:您通常可以将超过 140 个“客户端”连接到服务器(即具有良好的网络/硬件/内存)...
我建议始终使用真实场景(负载等)来测试这类事情来决定,因为有网络(性能、稳定性......)、硬件(服务器 RAM 等)和软件(什么是服务器到底是做什么的?)只能由您检查。
根据协议,您甚至可以/应该在其中放置一些超时/重新连接机制。
您的意思是查找会非常快 - 只需使用ConcurrentDictionary
来保存所需的信息,并以 IP:PORT 作为键(假设服务器在完整的 .NET 4 上运行)。
有关一些参考资料,请参阅:
http://msdn.microsoft.com/en-us/library/dd287191.aspx http://geekswithblogs.net/BlackRabbitCoder/archive/2011/02/17/c.net-little-wonders-the-concurrentdictionary.aspx编辑 - 根据 cmets:
保持 TCP/IP 连接不需要太多的客户端处理...它会消耗一些内存。我建议做一个小测试(1-2 个客户)来检查这个假设是否适合您的具体情况。
【讨论】:
那么长时间运行这么多连接不会受到惩罚吗? penalty 是“相对的”——这取决于你将它与什么进行比较...... OP 说他们需要定期在客户端和服务器之间实时交换数据......打开和关闭这么多连接可以阻碍性能并导致一些问题:相比之下,我怀疑坚持下去是可以的。添加了测试建议。 好吧有道理。感谢您的回复:D。 感谢链接和 cmets,这将在 .NET 3.5 下运行。我们不太担心服务器上的负载,更关心的是保持连接会对嵌入式设备产生什么影响,因为它在处理能力方面非常有限。 @Adrian 保持 TCP/IP 连接本身并不是处理密集型的,它通常会消耗一些内存...除非您计算嵌入式设备上的 CPU 周期和位数,否则我会假设不是一个真正的问题......从我的 POV 来看,通过一个小测试(只有一两个客户端保持连接)应该很容易评估这一点【参考方案3】:如果您谈论的是带有硬件设备的系统,那么我建议您在每次客户端完成发送数据时关闭连接。
为确保客户端从服务器获得一些更新,客户端可以等待 5 秒,以便任何数据从服务器到达。如果在此时间范围内/之前接收到数据,则关闭连接并处理数据。如果没有,则关闭连接,等待发送下一组数据。
这种方式缩放变得容易得多。保持连接打开总是会导致资源紧张,我认为没有必要,除非它是一些救生设备,如心率监测器、氧气供应监测器等,
【讨论】:
是否需要大量的底层活动(在客户端)才能真正保持连接打开?我原以为所有的压力都会放在我们不太关心的服务器上。 客户端应该做更少的逻辑工作,也应该有更少的代码。最好的选择是启用 OTA(无线)更新的客户端设备,您可以在其中通过网络本身更新嵌入式固件。这样一来,您无需在每次需要修复错误时都卸下设备,从而更加安全。以上是关于保持 140 个 TCP 连接?的主要内容,如果未能解决你的问题,请参考以下文章