TCP 连接是不是占用资源?
Posted
技术标签:
【中文标题】TCP 连接是不是占用资源?【英文标题】:Are TCP Connections resource intensive?TCP 连接是否占用资源? 【发布时间】:2011-12-12 05:57:10 【问题描述】:我有一个从一个(并且只有一个)客户端获取数据的 TCP 服务器。当此客户端发送数据时,它会与我的服务器建立连接,发送一条(逻辑)消息,然后不再在该连接上发送任何消息。
然后它将建立另一个连接以发送下一条消息。
我有一位同事说,从资源的角度来看,这非常糟糕。他说建立连接是资源密集型的,需要一段时间。他说我需要让这个客户端建立连接,然后只要我们需要通信(或直到出现错误)就继续使用它。
使用单独连接的一个好处是我可以多线程处理它们并在线获得更多吞吐量。我向我的同事提到了这一点,他告诉我打开很多套接字会杀死服务器。
这是真的吗?或者我可以只允许它为需要发送的每个逻辑消息建立单独的连接。 (请注意,逻辑消息是指可变长度的 xml 文件。)
【问题讨论】:
您当前的实施是否遇到任何问题?不要创建比必要更困难的解决方案。 【参考方案1】:这完全取决于您打算打开和关闭的连接数以及您打算打开它们的速率。
除非您通过中止连接而不是优雅地关闭它们来避免TIME_WAIT
状态,否则您将在客户端或服务器上累积处于TIME_WAIT
状态的套接字。对于单个客户,这些累积的位置实际上并不重要,因为问题是相同的。如果您使用连接的速率快于您的TIME_WAIT
连接关闭的速率,那么您最终将无法打开任何新连接,因为所有临时端口都在与TIME_WAIT
中的套接字一起使用。
我在这里更详细地写了这个:http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html
一般来说,我建议您保持一个连接,如果它被重置,只需重新打开它。逻辑可能看起来有点复杂,但系统的扩展性会好得多;您现在可能只有一个客户端,并且连接速率可能使您不会遇到TIME_WAIT
问题,但这些事实可能不会在您的系统生命周期内保持不变...
【讨论】:
【参考方案2】:从服务器的角度来看,打开大量连接不是问题。
How many socket connections can a web server handle?
从客户的角度来看,如果测量显示您需要避免启动连接的时间并且您需要并行性,那么您可以创建一个连接池。多个线程可以重用每个连接,并在完成后将它们释放回池中。这确实提高了复杂性,所以再一次确保你需要它。您还可以根据活动来缩小和扩大池的逻辑 - 当应用程序处于空闲状态时,在夜间保持与服务器的连接是可耻的。
【讨论】:
【参考方案3】:除了大家说的,考虑一下UDP。它非常适合不需要响应的小型消息,并且在本地网络(而不是 Internet)上它实际上是可靠的。
【讨论】:
+1 用于 UDP。通知样式消息更有意义。 感谢您的提示,但我必须确认消息。【参考方案4】:如果您的服务器只有一个客户端,我无法想象在实践中为每条消息打开一个新的 TCP 套接字会有任何问题。听起来您的同事喜欢过早地进行优化。
但是,如果您向服务器发送大量消息,这可能会成为一个问题。但是,对于一个客户,我不会担心。
只需确保在完成后关闭套接字即可。无需对服务器无礼:)
【讨论】:
【参考方案5】:TCP 连接的初始化序列是一个非常简单的 3 次握手,开销非常低。无需保持恒定的连接。
同时拥有许多 TCP 连接也不会那么快地杀死您的服务器。现代硬件和操作系统可以处理数百个并发 TCP 连接,除非您害怕拒绝服务攻击,这显然超出了这个问题的范围。
【讨论】:
知道我每分钟可以有 500 条逻辑消息的峰值有什么改变吗?或者这真的不重要吗? (我希望不会。) 如果每分钟 500 条消息只是一个峰值,而平均值大约是 20 条,则没有真正需要优化。如果 500 是一个稳定的速率,那么保持打开的连接可能是合乎逻辑的。 实际上,由于所有消息都来自同一个客户端并且可能不是并行发送的,因此 100 毫秒的不那么快的往返时间可能不会允许每秒 500 条消息的吞吐量。 那是每分钟 500 条消息(不是每秒 500 条)。以上是关于TCP 连接是不是占用资源?的主要内容,如果未能解决你的问题,请参考以下文章