【问题标题】:TCP/IP application Keepalive size, and bandwidth overheadTCP/IP 应用程序 Keepalive 大小和带宽开销
【发布时间】:2011-04-15 10:46:53
【问题描述】:

我正在编写一个 Java 服务器(java.net.Socketjava.net.ServerSocketjava.io.ObjectOutputStreamjava.io.ObjectInputStream),我知道分配给它的带宽有限。

我已经为我的输出和输入流编写了一个装饰器对象,所以我可以计算有多少字节通过它来进行分析。但这不会让我知道我用于连接的开销量。

我预计不会太多,但我想为此做好准备。我不会尝试对其进行优化,我只是想知道出于后勤原因(我必须请求多少带宽等)它将需要多少。

我不是第一个尝试获取此信息的人,但我似乎无法找到有关 Java 套接字和 TCP/IP 开销的好资源。 (也许那是因为没有什么值得注意的发现......如果我们的速度是每分钟 kb 的数量级,这真的不是什么大问题,但我还是想知道!)

谢谢!

【问题讨论】:

  • 您的带宽有限是因为服务器的连接速度很慢,还是因为您试图防止网络/服务器过载(或保持在上限)?
  • 首要考虑的是将带宽成本保持在最低水平。
  • 如果您的带宽有限,请不要使用 ObjectOutputStream,除非您非常小心,否则它非常冗长。 (通常这无关紧要)特定于应用程序的序列化可能会小几倍。

标签: java performance sockets tcp


【解决方案1】:

用我们目前掌握的信息来回答这个问题很有挑战性……例如,您所说的“开销”是什么?它只是 TCP ACK 数据包,还是数据负载以外的所有数据包开销(例如以太网、IP 和 tcp 标头)?

每分钟有多少连接?每个连接的平均数据传输量是多少?如果有很多非常短暂的连接,您的开销要求会上升(由于 3 次握手和连接关闭要求)......如果客户端不读取太多数据,但很多客户端,您也可能会有很高的开销一次保持连接打开数天。

老实说,在实验室中对此进行建模并做出一些关于每分钟命中率和并发客户端的假设会好 50 倍……这将为您提供一些大致数字。尝试将提供给应用程序的带宽限制在您的预算允许的最大范围内……然后开始回退……您可以在双端口 Linux 机器上使用 wanem 来限制带宽。

得到这样的实验室结果比理论计算要好得多。

HTH, \mike(他整天都在测试网络设备)

【讨论】:

  • +1 用于实验室方法。在应用程序上线之前我有一些时间(显然)所以我想我可以将分析推迟到稍后。不过,向工程师解释比向西装解释要容易! “你是什么意思,你不能分析它?”
  • 我想我不确定我是否理解分析和这之间的区别...请帮助填补空白...您将从分析中获得哪些数据是您无法通过检测获得的应用程序和运行实验室模拟?
  • 不是什么,而是什么时候。其他团队现在想知道应用程序的压力。
  • 呵呵,有时你可以直接把球踢回他们……让他们给你并发客户端的数量,以及每分钟的平均连接数。如果他们能够为您提供这些数字(即销售/营销),然后根据他们所说的对数据进行建模......将参数更改 +/- 30%,然后如果现实生活与他们不匹配叫你做模特,至少你有一些CYA...
  • 很难在这两个答案之间做出选择。 @Tim 实际上回答了我最初提出的问题,但现在我意识到这是两者中更有用的一个。
【解决方案2】:

TCP 开销因多种因素而异,但通常在满负荷时约为 5%。

基本上每个“数据包”都有 20 个字节的 IP 标头(如果是 IPv6,还有 20 个字节)加上 20-32 个字节的 TCP 标头。数据包大小因网络设备和条件而异,但通常在 1500 字节左右。

这个页面有一些细节:http://sd.wareonearth.com/~phil/net/overhead/

在我看来你可以完全忽略keep-alives,因为它们只在连接空闲时使用。

【讨论】:

  • 所以如果我的数据包平均只有 100 字节的信息,我的开销可能高达 52%,我明白了。
  • 是的,但请记住,您无法控制数据包的大小。许多小型发送调用可以使用“Nagel 算法”合并为一个,大型发送可以在发送系统或由路由器和源和目的地之间的交换机任意拆分。
  • 那么使用我的 Java 套接字,如果我使用 out.flush(),我不能保证生成通过网络发送的数据包?
  • A flush() 只保证传递给流的数据被传递到下一个级别。在内部,JVM 最终会调用一些操作系统服务,如 BSD 风格的send() API 或等效的,而将数据组合或拆分成数据包的决策发生在比这更低的级别。
  • 然而,我不应该说你有 no 控制权。您可以使用java.net.Socket.setTcpNoDelay() 告诉 TCP/IP 堆栈您想用更高的开销换取更低的延迟,即使没有这样,如果您发送一个字节并等待一段时间(毫秒),它发送一个字节的数据包。 setTcpNoDelay() 选项将减少或消除 TCP/IP 堆栈在通过网络发送数据包之前在 send 调用之间等待的时间,但这仍然只是一个建议,最终决定权不在您的手中,可能会有所不同包到下一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-31
  • 2021-04-17
  • 2012-08-30
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多