这周在忙压力测试的事情,用到了TCPCopy,是一个挺不错的工具。
TCPCopy是一种请求复制(所有基于tcp的packets)工具,可以把在线流量导入到测试系统中去。它具有真实、实时、低负载、分布式等特点。
TCPCopy七大功能:
- 分布式压力测试工具,利用在线数据,可以测试系统能够承受的压力大小(远比ab压力测试工具真实地多),也可以提前发现一些bug
- 普通上线测试,可以发现新系统是否稳定,提前发现上线过程中会出现的诸多问题,让开发者有信心上线
- 对比试验,同样请求,针对不同或不同版本程序,可以做性能对比等试验
- 流量放大功能,可以利用多种手段构造无限在线压力,满足中小网站压力测试要求
- 利用TCPCopy转发传统压力测试工具发出的请求,可以增加网络延迟,使其压力测试更加真实
- 热备份
- 实战演习(架构师必备)
TCPCopy分为TCPCopy client(也即tcpcopy)和TCPCopy server(也即intercept)。其中TCPCopy client运行在在线服务器上面,用来捕获在线请求数据包;TCPCopy server(默认监听端口为36524)运行在测试机器上面,用来截获响应包,并传递响应包头信息给TCPCopy client,以完成TCP交互。
使用方法如下:
TCPCopy server
# modprobe ip_queue # 启动内核模块 ip_queue # iptables -I OUTPUT -p tcp --sport <port> -j QUEUE # 设置要截获的端口,并且设置对output截获 # ./intercept
注意:如果已经启动 ip_queue 和已经设置 iptables ,只需要运行第3项。测试完以后要记得删除上面设置的iptables条目。
TCPCopy client
# ./tcpcopy -x <online server app port>-<test server ip>:<test server app port>
假设1.2.3.25,1.2.3.26是在线应用服务器,1.2.3.161是测试服务器,在线应用端口是11311,测试服务器的应用端口都是11511,我们的目的就是为了确认1.2.3.161测试服务器能否承受目前两台在线的压力。
我们利用TCPCopy进行测试:
目标测试服务器(1.2.3.161)
# modprobe ip_queue # iptables -I OUTPUT -p tcp --sport 11511 -j QUEUE # ./intercept
在线服务器(1.2.3.25)
# ./tcpcopy -x 11311-1.2.3.161:11511
在线服务器(1.2.3.26)
# ./tcpcopy -x 11311-1.2.3.161:11511
1.2.3.25:
21158 appuser 15 0 271m 226m 756 S 24.2 0.9 16410:57 asyn_server 9168 root 15 0 18436 12m 380 S 8.9 0.1 40:59.15 tcpcopy
1.2.3.26:
16708 appuser 15 0 268m 225m 756 S 25.8 0.9 17066:19 asyn_server 11662 root 15 0 17048 10m 372 S 9.3 0.0 53:51.49 tcpcopy
1.2.3.161:
27954 root 15 0 284m 57m 828 S 58.6 1.4 409:18.94 asyn_server 1476 root 15 0 14784 11m 308 S 7.7 0.3 49:36.93 intercept
1.2.3.25:
$ wc -l access_1109_09.log 7867867, 2185 reqs/sec
1.2.3.26:
$ wc -l access_1109_09.log 7843259, 2178 reqs/sec
1.2.3.161:
$ wc -l access_1109_09.log 15705229, 4362 reqs/sec
请求丢失率为:(7867867 + 7843259 - 15705229) / (7867867 + 7843259) = 0.0375%
从上面可以看出1.2.3.161测试服务器能够承受目前在线压力的两倍。
我们来看负载情况:tcpcopy自身负载占到8.9%和9.3%,intercept占到7.7%,从负载来看,均不高,内存也占得不多。
注意事项:
-
Linux平台,内核2.6+,需要支持netlink机制或者nfqueue(0.6.5+支持nfqueue,在 ./configure 指定nfqueue即可)。
-
TCPCopy中的 tcpcopy 和 intercept 程序运行需要 root 权限。
-
intercept 在同一台机器只需要运行一个实例就能支持多个应用的复制(设置多条 iptables 命令)。
-
TCPCopy client需要连接测试服务器(默认36524端口),所以要对外开放相应端口。
-
TCPCopy由于依赖于抓包函数,压力大的时候,抓包函数本身不可靠,所以会丢包,进而丢失请求。
-
由于 intercept 程序密切跟 ip_queue 内核模块相关,所以当压力很大的时候请求丢失率很高,需要优化 sysctl 系统参数才能达到好的效果:
通过 cat /proc/net/ip_queue ,查看 ip_queue 运行情况,如果Queue dropped的数值不断增大,则需要修改 ip_queue_maxlen 参数,比如 echo 4096 > /proc/sys/net/ipv4/ip_queue_maxlen ;如果Netlink dropped的数值不断增大,修改 net.core.rmem_max 和 net.core.wmem_max 参数, 比如sysctl -w net.core.rmem_max=16777216 和 sysctl -w net.core.wmem_max=16777216 。
-
如果要复制127.0.0.1发出的请求到另外一台机器,需要设置 -c 参数。
-
测试环境最好和在线环境一致,比如连接都保持keepalive。
-
TCPCopy只与ip、tcp层的数据有关,如果请求验证与tcp层以上的协议有关,则系统不能正常运行。例如:mysql连接协议,由于权限认证与tcp层上面的mysql协议有关,所以复制过去的请求会被目标测试服务器认为非法请求,这个时候需要针对mysql协议作具体针对性的处理,tcpcopy程序才能正常运行。
-
多层架构环境下,测试系统一定要独立,与在线系统没有业务关联,否则会影响在线。
-
丢失请求率跟网络状况有关,最好在内网内复制请求。
-
本系统不支持域名,只支持ip地址。
-
为了避免不必要的麻烦,关闭的时候先关闭 tcpcopy ,然后再关闭 intercept 。
更多信息参考文档: https://github.com/downloads/wangbin579/tcpcopy/TCPCopy_0.6.5_Manual.pdf