同一客户端访问多个负载均衡实例失败或超时

更新时间:2017-06-07 13:26:11

现象或问题

将相同 ECS 同时挂载在多个负载均衡实例的后端,并在这些负载均衡实例下创建相同的后端端口的四层监听。在这种场景下,用户用同一台客户端去同时访问这些负载均衡实例时,有时会出现失败或超时。

如下图所示,用户有两个负载均衡实例 SLB1 和 SLB2,分别有两个 TCP 监听,其前端端口不一致,但后端端口一致,并且这两个监听后端挂载了相同的云服务器 ECS。当一个用户 Client 去访问这两个 SLB 实例时,访问可能会失败。

架构图

解决方法

这种异常的具体原因为:

  • 四层 (TCP协议) 负载均衡会对用户的访问流量在入方向做 DNAT。

  • 当客户端访问 SLB1 时,CIP:CPORT->VIP1:VPORT1 的连接在到达后端 ECS 的时候,会被转换成 CIP:CPORT->DIP:DPORT。

  • 当客户端访问 SLB2 时,CIP:CPORT->VIP2:VPORT2 的连接在到达后端 ECS 的时候,也会被转换成 CIP:CPORT->DIP:DPORT。

  • 两条 TCP 连接的序列号和 TCP 状态在后端服务器上互相干扰,导致建连失败,即 Client 建立的两条连接在后端服务器上变成了同样的五元组 TCP:CIP:CPORT:DIP:DPORT。

注释:

  1. CIP: Client IP (客户端IP);
  2. VIP1: 负载均衡实例SLB1IP地址;
  3. VIP2: 负载均衡实例SLB2IP地址;
  4. VPORT1: 负载均衡实例SLB1的监听前端端口;
  5. VPORT2: 负载均衡实例SLB2的监听前端端口;
  6. DIP: 后端服务器的IP地址;
  7. DPORT: 后端服务器的端口;

解决方法为:

在这样的场景下,需要在后端服务器上避免出现同样的五元组,因协议类型固定为TCP,则需要调整后面的四元组组成。

  1. 避免CIP冲突: 如果后端服务是HTTP服务,可将其中一个SLB实例的四层监听切换为七层监听,七层SLB监听通过HTTP头部的X-Forward-For字段获取客户端源地址,二者不会产生冲突;另外,使用不同的Client访问这两个监听也可避免此问题出现。

  2. 避免CPORT冲突: 在Client发起针对VIP1、 VIP2的TCP建连请求时,指定源端口CPORT进行访问(如访问VIP1时使用CPORT范围是10000 – 29999,访问VIP2时使用CPORT范围是30000 – 49999)。

  3. 避免DIP冲突:即避免同一个后端服务器挂载在多个SLB实例后面。

  4. 避免DPORT冲突:如果后端服务非HTTP服务,则可将其中一个SLB实例四层监听的后端服务器服务端口修改,也可以避免该问题。