我是一名刚入行不久的 Web 开发人员。在一次面试中,我被要求设计一个消息系统,并设计一个系统来处理消息、格式错误的消息、不同的消息类型、状态日志等等……
我的问题是关于 TCP 上的数据包大小。
传入消息的速率为每秒 10,000 条消息,每条消息的大小为 2KB。我一直在尝试找到最大、最大安全或最大实际数据包大小限制。我在几个未经验证的地方(即非技术文档)看到最大理论大小为 64KB。对吗?在这种情况下,我发送 2KB 消息的示例很容易放入单个数据包中并降低此系统的复杂性。
如果 64KB 是一个不正确的数字,那么正确的数字应该是多少呢?此外,我不仅想了解最大理论大小,还想了解最大实际大小。我想涵盖消息可能略大于目标 2KB 的极端情况,并为 TCP 所需的各种标头留出空间。
答案1
以太网一直对 TCP/IP 数据包大小有影响。以太网的标准 MTU 为 1500 字节,在典型的 IPv4 报头开销为 20 字节和典型的现代 TCP 报头开销为 32 字节(过去为 20 字节,但现在我们添加了 12 字节的时间戳选项)之后,TCP 最大段大小为1448 字节。
PPPoE 在基于 DSL 的 ISP 中很流行,它又增加了 8 个字节的开销,因此经过 PPPoE 链路的 TCP 连接最终会得到 TCP MSS1440 字节. 其他技术可能会增加更多开销。
大多数现代 TCP/IP 堆栈都执行“路径 MTU 发现”(PMTUD),因此它们永远不必依赖 IP 碎片。不幸的是,一些网站会阻止 PMTUD 工作所需的 ICMP 消息,从而意外地创建了 PMTUD 无法工作的“PMTUD 黑洞”。为了让 PMTUD 黑洞背后的人仍能连接到他们的服务,Google 网站选择协商非常保守的 TCP MSS1380 字节(我上次检查时)。
因此,我想说,人们可以提出一个很好的论点,如果你想定制你的应用程序如何进行写入,以确保它们大多数时间只填充一个数据包,使你的写入不大于 1448 字节,也许不大于 1380 字节。
IPv4 数据报最大可达 64 KibiBytes,但互联网上只有极少数路径具有 64KiB MTU,因此该数字与大多数数据包大小规划无关。理论上,您的消息传递协议服务器可能连接到类似以太网的网络,该网络可能使用标准的 1500 字节帧,因此您自己的服务器的 IP 堆栈必须将 64KiB 写入分割成 46 个左右的独立数据包,然后才能在第一跳开始传输它们。即使是设置为使用非标准“巨型帧”的以太网网络,其最大 MTU 通常也为 9000 字节。我一时想不出有哪一种物理/数据链路(第 1/2 层)网络技术允许 64KiB MTU。也许是 Thunderbolt 上的 IP。