> 文档中心 > 每天15分钟JMeter入门篇(二):使用JMeter实现并发测试

每天15分钟JMeter入门篇(二):使用JMeter实现并发测试

每天15分钟JMeter入门篇(一):Hello JMeter
每天15分钟JMeter入门篇(二):使用JMeter实现并发测试
每天15分钟JMeter入门篇(三):认识JMeter的逻辑控制器
每天15分钟JMeter入门篇(四):认识JMeter中的函数
每天15分钟JMeter入门篇(五):认识JMeter中的Test Fragment
每天15分钟JMeter入门篇(六):学会用好JMeter中的断言
每天15分钟JMeter入门篇(七):认识JMeter中的监听器


每天15分钟JMeter入门篇(二):使用JMeter实现并发测试

  • 前言
  • 让我们开始吧
  • 构建并发测试的脚本
  • 事务控制器和聚合报告
  • JMeter我们走!
  • 简单的性能分析


前言

通过阅读以下内容,你可以:

  1. 使用JMeter实现一个真实的并发脚本;
  2. 了解JMeter并发中的基本设置;
  3. 了解JMeter中的事物控制器和聚合报告

在这篇文章的开始我们要先统一一个并发的概念,就是绝对并发和相对并发。纯粹意义上的绝对并发是不存在或者很难实现的,性能测试里的绝对并发,是指加了集合点的并发,也就是集合点上的请求在【极短】的时间内发送给服务器;相对并发就是多个线程不停的执行业务脚本,并不强调集合点,是否并发由线程的自由碰撞产生。对于这部分内容不同的公司、不同的文章、不同的作者都有不同的表述,这里不做概念上的争论,我只希望大家能明白,这篇文章里没有集合点,所以我们都是所谓的相对并发,大家理解一致就好。

让我们开始吧

首先回忆一下我们上一次实现的那个JMeter测试脚本,你应该已经有了一个可用的JMeter环境,并且具备了初步的手写代码的能力。在介绍并发测试的时候,我们仍然使用手写脚本的方式。不过一定要知道,JMeter做性能测试的时候,脚本生成效率最高的方式是通过代理录制的方式。这个以后会介绍。这里我们重点关注JMeter如何实现并发测试。

构建并发测试的脚本

首先把上次的脚本翻出来,它是用简书的首页作为目标系统的,我们再增加一个线程:进入IT技术,增加后类似以下这个样子
每天15分钟JMeter入门篇(二):使用JMeter实现并发测试
现在这个性能测试脚本,有一个测试场景(打开首页加载测试),这个场景下有两个测试用例分别是打开首页和进入IT技术。
我们先点击“首页加载测试”,右侧显示线程组设置界面:
每天15分钟JMeter入门篇(二):使用JMeter实现并发测试
这个界面里是并发测试的所有设置选项,都需要了解并且熟练掌握,你需要知道:它是什么、它是干什么的、它怎么用。这个阶段如果有概念弄不明白,后面的性能测试场景就会有卡壳的地方。

  • 【名称】:当前测试线程组的名称,建议写成有一定业务意义的场景名称,例如用户注册并发场景、用户登录并发场景、订单查询场景等,方便管理和使用
  • 【注释】 线程组的说明信息,写在这里的任何东西都不会影响脚本的执行
  • 【在取样器错误后要执行的动作】
    继续:线程组下的多个线程(例如“打开简书首页”和"进入简书-IT技术"线程),如果失败,则其他的线程会继续执行。设置继续就可以满足大部分的性能测试场景
    启动下一进程循环:如果执行过程中线程出现失败,则整个线程组下剩余的线程不再执行,重新回到线程组的第一个线程开始从头执行。最常见的如提交一篇文章、浏览文章、删除文章,如果提交文章都失败了,后面的线程就不要再执行了,执行了也是增加异常率
    停止线程: 如果线程组下的线程出现错误,则其他线程全部停止。也就是【当前】线程组就凉凉了。如果你的测试计划下有多个线程组,其他线程组不受影响。勾选这个选项很容易导致负载降低。目前还没有碰到需要停止线程的场景
    停止测试 : 当有线程出现错误时,【所有】线程组及正在执行的线程在运行完毕后,整个测试停止。也就是任意一个线程出问题后,其他线程在执行完毕后整个测试凉凉
    立即停止测试: 有线程出现错误,不管有没有正在执行的线程,即刻停止整个测试。
    在我所做过的性能测试中,90%以上的场景都是“继续”,其他四个选项只有在脚本的调试阶段和http接口的自动化测试中偶尔用到。是的,你没看错,用JMeter实现的http接口功能自动化测试。这部分内容在这个系列里不详细展开。
  • 【线程数】 你可以理解他就是并发数,你设置了10个线程,就相当于有10个终端在同时执行你的脚本,也就是10个并发。有的文章只管集合点叫并发,没有集合点的叫相对并发,概念不纠结,事儿都一样的事儿,就是由这么多的虚拟用户同时访问系统。
  • 【Ramp-Up时间(秒)】:线程从开始运行到完成加载的时间,例如100个线程你设置这个值为10秒,那么JMeter就会在10秒内完成100个线程的加载,也就是每秒加载10个;设置为0是所有的线程立即启动。在实际的压测中,100及以上的线程不建议设置立即启动,瞬发压力会影响性能测试的结果,例如你设置300线程立即执行,有可能一启动就先把压测机搞阻塞了。另一个应用场景是加载时间足够长,可以实现加载10个线程运行10分钟再加载10个线程运行10分钟,这种就是阶梯式加压。
  • 【循环次数】 勾选”永远“,则线程组一直循环执行,取消勾选则可以在后面输入循环次数。在实际的压测中选择”永远“,然后配合下面调度器中的”持续时间“,就可以实现测试场景运行时间的控制
  • 【Same user on each iteration】 :新版本JMeter增加,老的5.1.1和5.2.1没有。在每次的迭代循环中使用相同的用户名,如果是多用户并发测试时这个选项一定不要勾选。
  • 【延迟创建线程直到需要】:不勾选时,JMeter会在测试开始时立即创建所有的线程,有时这会导致在启动测试时测试机的CPU直接飙到100%,影响后续测试的执行,如果勾选,则JMeter会在需要的时候分配线程,至于什么是需要的时候,这个官方文档我也没看明白,暂时不讨论,以免误导大家。实际的压测中会根据效果调整,如果CPU没有瞬时飙升,这个复选框不勾选也可以。
  • 【调度器】
    勾选调度器复选框后,持续时间和启动延迟可选,持续时间就是整个测试计划的持续运行时间,就算你设置了线程组永远执行,这个持续时间一到,整个测试也会结束。启动延迟的目的是把不同线程组的启动时间间隔开,避免瞬时压力过大。启动延迟也根据实际情况来设置就好,原则就是脚本启动时如果CPU消耗在接受的范围内就不用调整,除非有其他特定的测试需求。
    这几个选项花点时间去掌握一下是有意义的,建议大家自己多设置几种不同的参数组合,运行一下观察它的运行效果,做到熟练应用。
    这里给出一个演示用的配置界面。
    每天15分钟JMeter入门篇(二):使用JMeter实现并发测试
    配置10个线程并发,5秒内加载完,也就是每秒加载2个线程,持续运行60秒。

事务控制器和聚合报告

在这里我们要给脚本增加一个事务控制器和聚合报告。性能测试里所谓的【事务】,就是指一组连续的http请求。例如你打开首页时,其实浏览器和服务器之间有多次请求,会下载多个静态文件,请求多个服务资源,我们会建一个事务控制器把这多个请求都放在一个事务控制器里,然后起一个有业务意义的名称。
增加事务控制器的作用是为了度量性能,增加聚合报告是为了查看性能。不增加事务控制器的话,聚合报告其实没有意义。
在线程组”首页加载测试“上右键——添加——逻辑控制器——事务控制器,起名”简书首页展示“,注意一定要勾选Generate parent sample,不然聚合报告会看得很痛苦。添加事务控制器后,选中“打开简书首页”和"进入简书-IT技术",剪切复制或者直接拖到事务控制器里。
在测试计划”简书性能测试“上右键——添加——监听器——聚合报告。

JMeter我们走!

到这里为止,一个简单的并发测试场景就建立起来了。更复杂性能测试场景会用到JMeter更多的特性,但是任何并发场景的基础都是刚才说的这些。
点击Run按钮,执行一下看看:
每天15分钟JMeter入门篇(二):使用JMeter实现并发测试
按照刚才的设置,你的聚合报告应该只有两行,一行总计一行事务,如果发现测试结果出现三行的,是因为你没有勾选Generate parent sample,导致JMeter把每个请求都度量出来了。是不是瞬间明白Generate parent sample的用途了,这就是所谓的说一百看一百不如亲手做一遍吧 (^_^)

简单的性能分析

我们可以简单的分析一下:

  • 在60秒里一共执行了4090个样本(请求),也就是tps是 4090 / 60 = 68.16/秒,跟后面的吞吐量是计算一致的。吞吐量还是不错的。
  • 90%的时间是154毫秒,响应非常快。注意那个平均值一般没什么用,反正我很少看平均值。
  • 异常率为0%,GOOD~所有的测试都完成了,说明服务状态良好,网站性能很高,其实这是废话,这可是简书的网站啊,各种高并发设计各种缓存各种消息队列,抗10个并发简直是毛毛雨,不过你也别为了好玩整上几万的并发,大部分的网站都有防DDoS攻击的策略的。再次强调,【以学习为目的,别乱并发】!
  • 接收数据明显高于发送数据,这也因为我们的脚本访问的都是网站数据,接收高于发送这倒是正常的。但是要注意一个现象,每秒2495KB的传输量,说明JMeter的脚本很可能没有304缓存或者本地缓存,导致每个线程都是从服务器重新下载的静态数据。【注意这对我们刚才的脚本来说不是问题】:因为我们访问的是/和/techareas,并没有什么可以缓存的资源,这就是实际的网络消耗。单独提出来这一点,是希望跟刚入门性能测试的朋友交流个心得,对于性能测试人员要时刻关注这种数据上的反常现象,要刨根究底搞清楚为什么。