欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【问题排查】记一次ab压测出现错误的原因分析

程序员文章站 2024-03-07 21:37:39
...

阅读本文大概需要 3 分钟。

用ab压测服务A (服务A会调用服务B) 的时候,并发不大的情况下,经常出现Failed requests, 最终发现原因是服务B所在服务器tcp半连接队列丢包,导致部分tcp连接不成功,最终请求失败,这里还原下整个过程分析下 (以下将服务A所在服务器称为客户端,服务B所在服务为服务器端)

问题现象

ab 压测出现Failed requests

【问题排查】记一次ab压测出现错误的原因分析

分析过程

1.客户端查看错误日志,看到错误原因

net/http: request canceled while waiting for connection

2.服务端根据客户端trace_id查找请求,日志里面找不到,怀疑是tcp层面的问题,也就是连接不成功,还没有进入应用层

3.服务器端查看tcp丢包情况,发现前后两次tcp半连接队列丢包个数相减正好是ab Failed requests个数3

# 查看半连接队列 (syns queue) 溢出 
netstat -s | grep drop
# 查看全连接队列 (accept queue) 溢出
netstat -s | grep TCPBacklogDrop

【问题排查】记一次ab压测出现错误的原因分析

半连接队列丢包

4. 查看丢包原因,服务器端查看半连接队列(syns queue)大小,排除不是设置得过小的原因

cat /etc/sysctl.conf | grep net.ipv4.tcp_max_syn_backlog

【问题排查】记一次ab压测出现错误的原因分析

TCP握手过程中建连接的流程和队列

5. 查看丢包的原因,通过查阅资料,服务器同时打开了tcp_timestamps + tcp_tw_recycle时,就会检查时间戳;如果对方发来的包的时间戳是乱跳的或者说时间戳是滞后的,这样服务器肯定不会回复,所以服务器就把带了“倒退”的时间戳的包当作是“recycle的tw连接的重传数据,不是新的请求,于是丢掉客户端的syn请求不回复

解决办法

vim /etc/sysctl.conf 
修改 net.ipv4.tcp_tw_recycle = 0 或者 net.ipv4.tcp_timestamps = 0
然后sysctl -p 重启

参考

https://blog.csdn.net/pyxllq/article/details/80351827
https://blog.csdn.net/GV7lZB0y87u7C/article/details/79358193

蔡蔡技术记

【问题排查】记一次ab压测出现错误的原因分析