大 IP 孤立连接

大 IP 孤立连接

首先我要声明,我对这个级别的网络的了解刚好够危险,所以如果我说了蠢话,还请见谅。

我在 3 台 Apache 服务器前使用 Big IP 负载均衡器。这 3 台 Apache 服务器都位于同一台物理机器上(运行 Linux),绑定到 3 个不同虚拟 IP 地址上的端口 80,但我认为这与此问题无关。我们已配置 LB,以便同一客户端每次都获得相同的 WEB 服务器,并通过 LB 提供的 cookie 进行控制。

如果我通过 LB 访问我们的应用程序,我偶尔(5-15% 的时间)会得到一个页面,其中浏览器只是旋转,永远不会返回。如果我直接访问每个 WEB 服务器,我永远不会得到这样的结果。使用 WireShark,我查看了我的 PC、LB 和我通过 LB 访问的 WEB 服务器上发生的情况,我看到了以下内容:

1) 大多数情况下,PC 用于访问 LB 的端口是 LB 用于访问 WEB 服务器的端口,我认为这是“正常的”;在我重现问题的所有 3 次中,端口都是不同的(例如,PC/LB 之间是 1234,LB/WEB 之间是 2345)。但并不是每次端口不同时我都看到了问题。这可能是一个转移注意力的借口……

2) PC <-> LB 通信使用长度为 1260 字节的数据包;LB -> WEB 数据包为 1260 字节,但 LB <- WEB 数据包是 1260 的倍数。当 WEB 向 LB 发送 2520 字节时,LB 会以 2x1260 字节数据包的形式接收它,并且只发送一个 ACK​​。然后它向 PC 发送回 2x1260 字节数据包,并从 PC 接收一个 ACK​​。我不明白为什么 2520 被分解成 2x1260,也不明白为什么 PC 知道只发送一个 ACK​​。这也可能是一个转移注意力的借口……

3) WEB 服务器在某个时刻向 LB 发送数据,但未收到 ACK,然后重新发送启动此数据序列的数据包。但我不知道为什么会发生重新传输,因为只过去了 0.6 秒,所以不可能是超时(好吧,我想可能是超时,但似乎不太可能)。此外,原始 WEB -> LB 数据包为 5040 字节(4x1260),但重新传输的数据包只有 1260。LB 收到了原始 5040 发送的所有 4 个数据包,但出于某种原因从未发送 ACK。我看到其他时候 LB 能够处理发送给它的 5040 字节,它确认得很好,所以发送数据包的长度似乎不是问题。但这些数据包都没有从 LB 发送回 PC。

4) 不过,只有第一个 1260 块数据从 WEB 重新发送到 LB。有一个短暂的延迟(0.4 秒),然后第二次重新传输数据,从第一个 1260 块开始,但这次所有 4x1260 数据包都重新发送。然而,LB 发回的 ACK 是针对所有 5 个重新发送的数据包的,即使其中一个显然被重新发送了两次(我根据 WireShark 显示的相对序列号得出此结论;发回的 ACK 等于第一个重新发送的数据包的序列号 + 5x1260,即使第二个重新发送的数据包的序列号与第一个重新发送的数据包相同)。这看起来真的很糟糕。

5) 我认为最糟糕的是端口全都乱了。原始对话端口如下:

PC <-> LB == 2723
LB <-> WEB == 2722

其中有一段对话是这样的:

PC <-> LB == 2722
LB <-> WEB == 2723

这足以让我眼花缭乱,但我确实根据数据包的内容验证了对话确实发生在我认为的端口上(呃)。第二次对话成功完成(事实上,这组端口上有两个对话,都成功完成)。在发送第一个(中止?)重新传输数据包之后,但在发送第二组 4x1260 重新传输之前,有一次对话:

PC <-> LB == 2722
LB <-> WEB == 2722

因此,端口 2722 上的原始 LB <-> WEB 对话被中断。我认为协议不允许这种情况发生。此端口上没有向任何方向发送 FIN 或 SYN。对于此新发起的对话,LB -> WEB 发送的序列号与我预期的一致。WEB 向 LB 发送的 ACK 具有正确的序列号,但 ACK 偏离了(正好偏离了 1260)。

第二次对话似乎从未发生过,因为在重新传输 4x1260 后,WEB 发送了另一个新的 1260 数据块,并且所有数据都是来自原始请求的响应(通过检查数据包中的数据确定)。然后 LB 发回一个 ACK​​,这是我从原始对话中期望的(最后一个 ACK​​ + 4x1260 + 1260)。

所以,我知道发生了什么,但不知道为什么会发生,当然也不知道如何修复它。我该怎么做?

编辑:我刚想起来一件事;在 WEB 向 LB 重新发送 4x1260 的过程中,LB 发送回的 ACK 恰好比我预期的多 100 个字节。不过,在发送了第一个 1260 个新数据包后,LB 发送回的 ACK 恰好是它应该有的(即它进行了自我更正)。我不知道这是怎么发生的,也不知道这意味着什么,甚至不知道它是否有意义。

答案1

让我印象深刻的一件事是,您的 Web 服务器位于使用不同 IP 地址的同一台机器上。如果您将所有服务器都放在一个盒子里,负载平衡实际上不会带来任何好处。

您描述的数据包中的某些内容似乎很正常;您是否使用过 Wireshark 的“专家信息”和“跟踪 TCP 流”功能?这些功能将显示 TCP 连接的更高级别视图。另外请记住,Wireshark 可能不会捕获所有数据包(尤其是当您使用千兆以太网时)。

至于问题,您可能看到 LB 中有一个错误,这是由于您的所有 Web 服务都位于同一个框中,这意味着您的三个 IP 地址都具有相同的 MAC 地址。如果 LB 使用 MAC 地址跟踪连接,它可能会混淆您的三个服务器 IP 地址并将数据包定向到错误的位置。

答案2

  1. 客户端和 BIG-IP 服务器端(现在是 Web 服务器的客户端)的 TCP 端口将根据需要进行更改。这是预期行为,因为 BIG-IP 处理与客户端和服务器的完全独立的 TCP 连接。

  2. 由于代理处理客户端和服务器之间的单独连接,因此正常的 TCP 行为在连接的客户端和服务器端会有所不同。您应用的 TCP 配置文件以及代理的哪一侧(您可以根据使用情况和网络环境对连接的客户端和服务器端应用不同的配置文件或对两者应用相同的配置文件)将改变实际在线路上传输的数据、时间以及发送确认的数量和频率。

  3. 重传很常见,而 tcp 堆栈如何处理网络拥塞取决于连接的客户端和服务器端的现有堆栈。同样,对于任何客户端->BIG-IP->服务器场景,您都有两个客户端和两个服务器。

  4. 需要查看整个捕获过程才能诊断您所看到的行为。

  5. 不要认为 tcp 端口是这里需要担心的问题。

如果不了解详细信息,我猜您启用了常规 tcp 配置文件而不是自定义配置文件,并且它对您的应用程序表现不佳。我强烈建议使用自定义配置文件,并聘请了解 TCP 流和拥塞控制算法如何工作以及 TCP 配置文件中的哪些设置对某些应用程序表现不佳的人。几年前,我们撰写了关于 BIG-IP TCP 配置文件的 10 部分系列文章(可能需要更新所有更改,但它仍然是一个很好的信息来源),我认为这会有所帮助:https://devcentral.f5.com/articles/investigating-the-ltm-tcp-profile-nagles-algorithm

相关内容