浅谈HTTP接口性能测试脚本的编写


作为测试界的老司机,最近接到一项任务需要写新的性能测试代码。由于之前的测试代码风格和自己习惯的编码风格差别实在太大,因此放弃了模仿原来的测试代码继续添加测试用例的想法,自己从头开始写了一些测试代码。


结果,进行测试过程中居然出现了问题,问题问题……


问题发现

在用自己新写的测试代码测试一个文件下载接口的时候,发现了一个奇怪的现象,在并发比较小的情况下(50并发),TPS、响应时间什么的一切看起来都很正常。但是当并发加到100+时,TPS曲线就变得很神奇了,同时还有部分请求失败,测试结果如图1所示:



图 1 并发100+性能测试结果


被测系统的架构相对简单,业务服务前端搭个Nginx,客户端请求都是把请求发送到Nginx,然后通过Nginx转发到业务服务器。 测试环境架构如图2所示,被测服务为图2中的NefsProxy:

图 2 测试环境架构图

原因查找
通过查看测试脚本的日志发现, 所有的错误 都是由于建立连接失败引起的,登录到Nginx所在服务器上使用netstat命令查看连接数,发现测试过程中连接数很高,高的时候能达到3000—4000。为了确认上述问题是否是由于测试脚本有问题而引起的,我马上用老的测试脚本跑了一轮测试。结果很明显,老的测试脚本跑的测试结果一切正常,TPS也比新脚本的结果高不少,并且没有失败。因此可以断定是测试脚本的问题。


接下来就要寻找原因了:


→首先怀疑是不是测试脚本在每个请求结束后没有释放连接。问题的现象是连接数高导致新连接被Nginx拒绝。但是review了代码后,发现每次请求结束后都调用了:


因此,应该不是测试客户端没有主动释放连接引起的。


→后来想起Nginx配置了将请求强制转换为长连接。

Nginx的配置如下:


问题好像有点头绪了。一般配置长连接是为了提高服务端性能,为什么在我的测试中反而起到了反作用呢?


→接下来就要回过头来好好看看自己测试代码的实现逻辑了。


其中,NosObjectOperation.getObject是java代码实现的,每次getObject方法被调用时,会new一个HttpClient对象,然后通过HttpClient发送Http请求。


到这里,问题的本质慢慢浮出水面:客户端每发送一次请求,都会new一个HttpClient,并与Nginx新建一个连接,而Nginx这边又设置了强制长连接,每个Worker的最大空闲连接数为1024(keepalive 1024)。同时,测试环境的Nginx配置了4个Worker。因此,Nginx最多会保持4096个空闲连接。所以,由于连接数过多,在空闲连接被释放前,新的连接可能就会被拒绝。


问题解决

既然问题的原因找到了,该怎么修改测试脚本呢?


当然最简单的就是每个请求处理结束后强制将连接关闭。这样虽然能解决连接数多的问题,但是也同时间接的让Nginx强制长连接的配置失效了,达不到长连接提升性能的目的。


因此,我采用了这样的解决方法:尽量模拟真实的用户场景,每个测试线程使用一个HttpClient对象(也就是在python脚本的__init__方法里new一个HttpClient对象,getObject测试方法都调用这个对象发送Http请求,同时java方法nosObjectOperation.getObject也不再每次自己创建新的HttpClient对象,而使用传入的在Python脚本方法__init__中创建的HttpClient对象):



Attention:使用grinder进行性能测试时,每次创建测试线程时会调用__init__方法,也就是说有多少个并发线程,就会被调用多少次。通过这样的修改,如果测试时是100个并发线程,那测试客户端和Nginx之间就只会有100个ESTABLISHED的连接。


问题解决了,用新的脚本跑一次测试,结果如图3所示,很让人满意:

图 3 修改测试脚本后并发100+性能测试结果


注意,总结!总结!总结!

1)做性能测试,测试脚本的编写也是一个很重要的环节,只有模拟真实用户使用情况的脚本才能跑出真实的、有参考意义的性能测试结果。


2)当性能测试结果与预期不一致时,定位问题时首先要看测试脚本是否有问题,并对测试环境的各项配置(Nginx、Tomcat等)进行梳理。


3)当使用grinder测试框架进行比较复杂的性能测试,编写测试脚本时要弄清楚grinder测试框架的运行机理,各项配置的作用等。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值