三、压力测试
1. 性能测试 vs 压力测试
性能测试(Performance Test)主要测试系统是否满足性能要求,同时可能为了保留系统的扩展空间而进行的一些稍稍超过“正常”范围的测试,比如:当前系统使用用户100人,可能未来人数会增多到300人,所以要让系统能够在300人情况下正常运行。
压力测试(Stress Test)是测试在一定的负载下系统长时间运行的稳定性。压力测试尤其关注大业务量情况下长时间运行的系统性能变化,如:是否反应变慢、是否会内存泄漏导致系统逐渐崩溃、是否能恢复。
通俗地讲,压力测试是性能测试的一部分,但它们有所区别:
- 性能测试是验证应用系统满足性能需求;
- 压力测试更加“暴力”,它是为了发现在什么条件下应用系统的性能变得不可接受,是找到极限值。
2. 压力测试的步骤

2.1 明确测试目标
- 确定存量数据的规模:一般会要求制造出3~5年的存量数据;
- 确定需要进行压力测试的业务:一般是用户使用最频繁,或者业务操作复杂的业务;
- 确定操作用户的的数量、各类操作用户的比例;
- 确定峰值业务量的要求:一般是1个小时内最多要处理的笔数;
- 确定对交易类业务响应时间的要求:如在峰值情况下,单笔业务的处理时间小于2秒;
- 确定对于批量类业务响应时间的要求:如进行日终、月终、年终的处理时间,与外系统间批量数据传输的时间。
2.2 构建压力测试场景
为了进行压力测试的技术准备,需要阅读如下资料:
- 系统概要设计:了解系统技术架构,确定测试方法;
- 操作手册:了解系统使用过程;
- 程序/接口设计文档:如果是自己团队开发的;
- 分析http交互过程:如果是别人家的程序。
为了开发压力测试脚本需要:
- 准备测试环境,压力测试一般要求环境配置较高,最好与生产环境一致或者接近;
- 参数化脚本;
- 脚本回放,验证脚本是否可以成功的执行。
2.3 执行压力测试:
- 单用户运行压力测试场景;
- 多用户运行测试场景,查看系统资源消耗等
- 阅读压力测试报告,开始调优工作。
3. 压力测试关键指标
压力测试结束后会产生一个测试报告,报告中应该至少包含如下的指标:
- 样本(Samples):表示测试中一共发出了多少个请求,如果模拟10个用户,每个用户迭代10次,那么样本总数就是100;
- 平均值(Average):平均响应时间;
- 中位数(Median):50%用户的响应时间;
- 90%百分位(90% Line):90%用户的响应时间;
- 95%百分位(95% Line):95%用户的响应时间;
- 99%百分位(99% Line):99%用户的响应时间;
- 最小值(Min):最小响应时间;
- 最大值(Max):最大响应时间;
- 异常 %(Error %):本次测试中出现请求错误的数量/请求的总数;
- 吞吐量(Throughput):默认情况下表示每秒完成的请求数;
- 接收(Received) KB/sec:每秒从接收到的数据量;
- 发送(Sent) KB/sec:每秒发送给服务器端的数据量。
明白如上测试指标的含义,可以帮助我们读懂测试报告,分析性能瓶颈,进而提供优化方向。
4. 压力测试工具JMeter
Apache JMeter是Apache组织开发的基于Java的压力测试工具。其实有很多压力测试工具,选择jmeter的主要原因是开源、免费,而且易用、足够用。
下载及安装方法:
- 注意:jmeter依赖java运行,因此要先安装jdk。
- 打开浏览器,输入网址“https://jmeter.apache.org/”;
- 在页面的左侧菜单中,点击“Download Releases”链接;
- 在下载页面,找到类似“apcahe-jmeer-5.x.x.zip”的链接,然后点击开始下载;
- 下载完成后,把文件解压到某个盘符下的“apcahe-jmeer-5.x.x”目录中;
- 进入子目录“bin”,双击“jmeter.bat”即可运行程序。
![]()
jmeter刚运行时,显示的是英文界面,可以点击菜单“Options>Choose Language>Chinese(Simplified)”,切换到中文。
5. 压力测试实战
我用“携程网站查询航班”的功能为例,给大家演示如何使用“浏览器调试+jmeter”进行压力测试。
![]()
- 打开chrome浏览器,在地址栏输入“ctrip.com”,回车打开携程网主页;
- 在页面的左侧点击“机票”,看到机票查询对话框;
- 填写任意的出发城市、到达城市、出发日期;
- 在点击“搜索机票”按钮前,一定要先按F12键,打开“开发者工具”,这样我们在能够捕获到http交互信息。
![]()
- 在“开发者工具”上,点击“Network”标签,查看http信息;
- 点击“Time”列,确保下方的列表数据按照响应时长的倒序排序。这么做是因为大多数情况下,来自服务器端的数据处理都比较耗时,便于我们找到想要的信息;
- “products”排在最前面,点击它,看看http的详情。
![]()
- 先点击“Preview”或“Response”标签,看看服务器返回来的是否我们想要的数据。“Response”中显示的是原文,相比较之下,“Response”中的可阅读性更友好一点,但它们的内容实际是一样的;
- 预览json数据,我们发现了“城市、航班”数据,我们的运气比较好,比较顺利就找到了想找的http交互,接下来就是分析参数了。
不得不说一句:携程返回的航班查询结果数据很大,如果保存为文本文件可达到2M以上。数据量大是因为承运的航空公司多、起飞时刻多、每个航班的价格也多。
![]()
参考上图,各个参数的意义如下:
- Request URL包含我们想要测试的网址;请求方法是post;
- 服务器端口是443;
- 为了查询,发送给服务器的cookie在这里;
- 为了查询,发送给服务器的浏览器客户端参数在这里;
- 为了查询,发送给服务器的航班查询参数在这里。
以上信息很重要,需要把它们复制下来,在后续的jmeter压力测试中使用。
![]()
- 打开jmete,刚运行时显示的是英文界面,可以点击菜单“Options>Choose Language>Chinese(Simplified)”,切换到中文;
- 更改“测试计划名称”为“航班查询压力测试”。
![]()
- 在左侧选择、并右键单击“航班查询压力测试”,然后在弹出菜单中选择并单击“添加>线程(用户)>线程组”,完成线程组创建;
- 在左侧选择新创建的线程组,然后右键单击,在弹出菜单中选择并单击“添加>取样器>HTTP请求”;右键单击,在弹出菜单中选择并单击“添加>配置元件>HTTP信息头管理器”;右键单击,在弹出菜单中选择并单击“添加>监听器>查看结果树”;右键单击,在弹出菜单中选择并单击“添加>监听器>聚合报告”。
在添加以上内容的时候,你会发现jmeter提供了很多可选的组件。其中以上内容,是我们完成本次测试必须的:
- HTTP信息头管理器,用于组织要发送给服务器的http头参数(本例中要把content-type、cookie、user-agent配置在这里);
- HTTP请求,用于组织要发送给服务器的数据(本例中就是航班查询参数);
- 查看结果树,用于保存从服务器返回的数据;
- 聚合报告,用于查看测试结束后的压力测试报告;
- 线程组,是我们可以配置并发量的地方,默认情况下是单线程的,也就是1个用户,我们先保持默认值不变,并在所有参数配置好、验证可行后再增加并发量。
![]()
在左侧点击“HTTP请求”,然后配置上面的参数值。这些值,均来自前面用“开发者工具”捕获的参数,对应关系如下:
- 把“Request URL”拆分为“协议”、“服务器名称或IP”、“路径”;
- 把“Request Payload”的内容复制后填在“消息体数据”中;
- 本案例中,http请求方法是post、端口号是443、内容编码是utf-8。
![]()
- 在左侧点击“HTTP信息头管理器”,进入配置界面;
- 点击“添加”按钮;
- 依次添加“content-type”、“cookie”、“user-agent”三个头参数,它们的取值来自前面“浏览器调试”捕获的结果,复制过来即可。
![]()
- 配置完成后,点击“启动”按钮,即可开始测试单线程下,是否可以正确测试;
- 测试执行完成后,点击左侧的“查看结果树”,就可以确认执行情况;
- 如果这里有“200 OK”的字样,说明执行成功了;
- 如果想看看返回的航班查询结果数据,那么点击“响应数据”即可。
![]()
- 点击左侧的“聚合报告”,可以查看测试报告;
- 由于我们进行了默认的单线程测试,因此样本数等于1,在这种情况下,平均值、各种中位值、最小值、最大值都是一样的,上面截图是3126ms,该值在不同的测试机上会有所不同。
![]()
单线程的测试,只是为了验证测试参数都配置正确了。接下来就开始配置多线程的测试:
- 在左侧点击“线程组”, 进入线程量属性配置对话框;
- 设置线程数为50、Ramp-Up时间为5秒、循环次数为1;
- 点击“启动”按钮,开始多线程并发测试。
上面我们用到了三个线程属性,它们的说明如下:
- 线程数:简单的说,就是模拟的用户量;
- Ramp-Up时间:用于告知JMeter 要在多长时间内建立全部的线程。默认值是0,JMeter将立即建立所有线程。假设ramp-up period 设置成T秒,全部线程数设置成N个,JMeter将每隔T/N秒建立一个线程。
- 循环次数:默认为1,表示并发测试只执行一轮。如果勾选上“永远”,那么测试将一直进行下去,除非点击上方“启动”旁边的“停止”来中断测试。
![]()
以上执行需要一段时间,执行完毕后,可以再次查看“聚合报告”。需要说明的是:
- 测试环境不一样,测试结果也会不一样;
- 总的来说携程在大并发量的情况下性能仍然没有滑坡;
- 携程对恶意查询设置了防御措施,连续启动几次后,就暂时不能测试了。
6. 压力测试小结
如果是对我们自己开发的应用程序进行测试,那么在构建好测试参数后,可以逐步增加测试并发量,进行多轮次的压力测试,直到关键测试指标值达到不可接受的程度,那么就得到了应用系统的性能上限。
本章节只是对使用jmeter进行压力测试的入门,jmeter本身还提供了更多的功能,详情可参考官方的用户手册。
网友评论