过去几天我一直在挠头,试图为以下问题提出解决方案:
在我们的数据中心,我们有一个运行在 BigIP 硬件上的 F5,它充当来自全国各地不同办公地点的客户端机器的 HTTPS 请求的单一入口点。F5 终止 TLS,然后将所有请求转发到两个 Traefik 负载均衡器,后者将请求路由到各种服务实例(Traefik 节点在 Red Hat Enterprise 上的 Docker 中运行,但我认为这与我的问题无关)。从吞吐量、CPU 和内存的角度来看,这三个网络组件完全有能力处理大量请求和流量,并有足够的备用容量。
但是,我们注意到客户端发出的 HTTP(S) 请求频繁出现 1000 毫秒的延迟,尤其是在高负载时间。我们将问题跟踪到以下根本原因:
- 在高负载期间,F5“客户端”以高频率(可能每秒 100+)向 Traefik“服务器”节点发起新的 TCP 连接。
- 当 HTTP 响应返回时,这些连接在 Traefik“服务器”端终止。
- 每个关闭的连接在 Traefik 主机上保持 TIME_WAIT 状态 60 秒。
- 当 F5 发起新连接时,它会从其临时端口范围中随机选择一个可用端口。
- 有时(通常在高负载期间),Traefik 中已经有一个处于 TIME_WAIT 状态的连接,具有相同的源 IP + 端口、目标 IP + 端口组合。发生这种情况时,Traefik 主机上的 TCP 堆栈 (?) 会忽略第一个 SYN 数据包。注意:RFC 6056称此为 instance-ids 的冲突。
- 1000 毫秒后,重传超时 (RTO) 机制在 F5 上启动并重新发送 SYN 数据包。这次 Traefik 主机接受了连接并正确完成了请求。
显然,那些 1000 毫秒的延迟是绝对不能接受的。所以到目前为止我们已经考虑了以下解决方案: …