容器内核参数引发的tps断崖问题定位思路

tps断崖

image.png

定位网络问题

查询nginx所在服务器在那台机器上面 image.png

查询nginx的网络命名空间地址 image.png

查找网络id我们架构用的docker-swarm所以网络走的swarm_net找到对应的id 进入容器 image.png

查询网关的vip地址:docker service inspect 服务名 image.png

运用iptables -nvL -t mangle查看网络情况把0x148 16进制转换10进制后

image.png

由于LVS(IPVS)是工作在内核空间的,因此要在用户空间对其进行配置和管理就要用到ipvsadm,ipvsadm是LVS在用户空间的管理命令。运用ipvsadm –l

148十六进制转换成10进制后得到328,找到328可以看到负载到了四个网关ip地址上面采用了最简单的rr轮询算法转发 image.png image.png

ipvsadm -l -n –c查看网络转发的信息及连接状态,161为nginx容器ip,98为网关的VIP 最后一列为四个网关实例容器ip image.png

此时我们看到TIME_WAIT状态存在很多,负载均衡主动发起关闭连接 状态从FIN_WAIT2 进入 TIME_WAIT等待服务端ACK 才会进入CLOSE

说明服务端一直没有给到确认包导致大量的timewait等待

查看负载均衡的超时时间,看到有120s的超时设置 image.png

修改swarm lb网络空间系统内核参数:

conn_resue_mode=1 的bug
开启这个内核参数实际就表示 ipvs 转发时不做连接复用,每次新建的连接都会重新调度 rs 并新建 ip_vs_conn,实际在服务器完成与服务的连接后,它最终处于 TIME_WAIT 状态。该状态保持 2 分钟(与上面的负载均衡的超时时间一致),然后从 conntrack 表中删除连接。如果在这 2 分钟内客户端尝试重用相同的端口,则在接收到 SYN 时,连接将从 conntrack 表中删除,SYN 不会转发到后端服务器,也不会将 ACK 发送回客户端,就会丢失第一个SYN包,在一秒钟后强制执行来自客户端的重传。这是从客户端感知的,因为服务器需要 1 秒才能响应,从而导建连性能急剧下降。 修复:**conn_resue_mode=0 即启用ipvs 连接复用的能力 ** 利弊分析:如果该 mode 是 0,只要有client ip:client port 匹配ip_vs_conn 就直接转发到所复用连接对应的rs上,会导致一些新建立连接被“固化”到部分rs上。使得连接不均衡,但可以提高qps性能。

该参数在docker网络命名空间中进行修改,由于上周国家电网检查,机房断电导致服务重启命名空间变更,之前的配置丢失!

运维优化之前nginx断崖的参数后 TPS趋于平稳,下图为修改后压测结果(服务都为4实例)

image.png