负载均衡下linux建立链接失败的问题

该问题可能与linux的操作系统参数tcp_tw_recycle和tcp_timestamps有关系,理论的解释如下:

如下为tcpip握手部分的linux源码:
if (tmp_opt.saw_tstamp &&
tcp_death_row.sysctl_tw_recycle &&
(dst = inet_csk_route_req(sk, req)) != NULL &&
(peer = rt_get_peer((struct rtable *)dst)) != NULL &&
peer->v4daddr == saddr) {
if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
(s32)(peer->tcp_ts – req->ts_recent) >
TCP_PAWS_WINDOW) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
goto drop_and_release;
}
}
tmp_opt.saw_tstamp:该socket支持tcp_timestamp
sysctl_tw_recycle:本机系统开启tcp_tw_recycle选项
TCP_PAWS_MSL:60s,该条件判断表示该源ip的上次tcp通讯发生在60s内
TCP_PAWS_WINDOW:该条件判断表示该源ip的上次tcp通讯的timestamp 大于本次tcp

LINUX当前的参数设置为tcp_tw_recycle=1, tcp_timestamps=1,在这种配置下,如果后一个SYN的timestamp属性比前一个SYN的要小,LINUX就不会为后一个SYN发送ACK,导致问题现象。

这就能解释为什么本地服务器的syn包有时候已经到对方没有回报文,有时候有时好的,导致不能建立链接。

建议的的方案:
1、 先把临时上线的两台测试服务器的操作系统参数修改tcp_timestamps关闭,tcp_tw_recycle修改为打开,切换防火墙验证是否可行
具体操作:
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 0 > /proc/sys/net/ipv4/tcp_timestamps

云平台虚拟机修改root口令

1. 停止虚拟机
virsh destroy instance-000007c4
2. 挂载虚拟机的磁盘文件:
qemu-nbd –c /dev/nbd15 /dsx01/instances/instance-000007c4
kpartx –a /dev/nbd15
mkdir –p /tmp/tmpClone
mount /dev/mapper/nbd15p1 /tmp/tmpClone
3. 生成root用户的密码,这里密码就是root,(虚拟机原密码不是root)
openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32) 4. 将生成的字符串替换/etc/shadow文件中root的用户密码(替换整个第二个分段): 保存并退出。 5. 卸载磁盘文件: umount /dev/mapper/nbd15p1 kpartx –d /dev/nbd15 qemu-nbd –d /dev/nbd15 6. 打开虚拟机并登陆 virsh start instance-000007c4 ssh root@$ip