JMeter多个请求按照比例并发压测的几种方式

发表于:2023-1-09 09:40

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:十八岁    来源:博客园

#
Jmeter
#
jmeter
分享:
  一、需求
  在压测的过程中,为了能够压测整个链路,通常需要多个接口进行并发, 每个接口的请求比例不尽相同。
  比如此时此刻,我在写博客,很多人在浏览博客,或者点赞、评论博客等等等,这些行为占比是不同的。
  那么,我们怎么才能尽可能的模拟线上真实场景,对每个接口按照比例并发呢?
  二、实现方法
  设定一个用作讲解的并发场景:
  比如,同一时刻,点赞博客的请求占比10%,查看博客的请求占比90%,比例是1:9。
  1、对每个请求设置循环次数
  如上场景,我们可以为查看博客的请求设置循环次数为9。
  右击【查看】请求→【插入上级】→【逻辑控制器】→【循环控制器】→【循环次数】设置为9→【运行】→【查看结果树】
  在请求的名称后面加上这个参数,就可以看到请请求的顺序:${__counter(true,i)}
  ${__threadNum}:统计线程数
  ${__counter(true,i)}:只统计该用户的迭代次数,
  ${__counter(false,i)}:统计所有用户的迭代次数,
  ${__threadNum}_${__counter(true,i):统计每个线程下,每个用户的迭代次数。
  可以看出,【点赞】请求执行了1次,【查看】请求执行了9次。
  2、通过switch controller来实现实现
  switch controller类似于程序中的switch函数,该Controller根据给定的值n(可以使用参数)选择执行其下的第n个子节点。
  JMeter取样器按顺序编号,第一个取样器(请求)编号为0,第二个为1,以此类推。
  如果指定的编号超出了下面的节点数或者不指定,则运行第0个取样器。
  如上例,我们给定的值n应该是{0,1,1,1,1,1,1,1,1,1};
  0代表执行第一个取样器,也就是其下的第一个子节点——【点赞】请求; 1代表执行第二个取样器,也就是其下的第一个子节点——【查看】请求。
  为了更符合线上实际场景,我们用一个random随机数来控制请求的执行顺序,而不是像方法1那样顺序执行。
  操作步骤如下:
  ①添加BeanShell 取样器及脚本
  右击【线程组】→【添加】→【取样器】→【BeanShell 取样器】→添加如下脚本
  import java.util.Random;
  //设置比例为1:9
  int[] values = {0,1,1,1,1,1,1,1,1,1};
  //利用random随机函数来按照比例随机执行http请求
  int size = values.length;
  Random rd = new Random();
  int n = rd.nextInt(size-1);
  System.out.println("value:"+values[n]);
  //新建参数"SWITCH_VALUE",并将通过随机函数得到的取样器赋值给参数
  vars.put("SWITCH_VALUE",String.valueOf(values[n]));
  ②添加Switch控制器
  右击【线程组】→【添加】→【逻辑控制器】→【switch 控制器】→设置控制变量,即上一步脚本里设置的参数“SWITCH_VALUE”→运行线程组
  可以看出,我们共10条请求,【点赞】1条,【查看】9条。与我们最初设置的1:9的比例一致。
  3、通过自定义随机变量+if控制器来实现
  如上场景,我们可以通过Java脚本自定义一个min-max的随机数,然后用if控制器来控制发送哪个请求。
  如上场景,点赞与查看是1:9,我们可以定义一个生成1-10的随机数,用if控制器来控制,if 随机数=1,则执行【点赞】请求,if随机数>1,则执行【查看】请求。
  具体步骤如下:
  ①自定义随机变量
  选择线程组→【添加】→【取样器】→【Java请求】 (因为要写Java脚本,所以需要先添加Java请求,在Java请求下添加取样器)
  选择【Java请求】→【添加】→【前置处理器】→【BeanShell PreProcessor】→添加 设置自定义变量的脚本,生成随机数【randNo】
  //.......自定义随机数的方法一........
  import java.util.Random;
  class JmeterUtil{
      public static int getRandNo(int min,int max){
          Random random = new Random();
          int randNo = random.nextInt(max)%(max-min+1) + min;
          return randNo;
      }
  }
  int r = JmeterUtil.getRandNo(1,10);
  vars.put("randNo",r.toString());
  //.......自定义随机数的方法二........
  vars.put("randNo","${_Random(1,10)}");
  ②为每个请求添加if控制器,来控制比例
  右击【点赞】/【查看】请求→【插入上级】→【逻辑控制器】→【如果(If)控制器】→添加随机数【randNo】的判断
  在这里要注意,这里只能填一个变量来作为判断条件,而不能直接填【${randNo}=1】,这样if控制器是无法解析的,所以,我们要内置jexl3函数来实现表达式的计算。
  步骤如下:
  点击【工具】→选择【函数助手对话框】→选择【jexl3】函数→将表达式填入函数参数的【值】那一列→点击【生成】→点击生成的函数即可复制→将复制的函数表达式粘贴在if的判断条件框里。
   这里是点赞的if控制器,点赞的比例是1,所以我们的判断条件为randNo==1。
   【查看】请求的if控制器设置同上,只是判断表达式由【&{randNo}==1】改为【&{randNo}>1】
   运行结果如下:
   可以看出,比例基本一致,【点赞】请求有2个,【查看】请求有8个,随机数不是10个数一定是1-10都会出现,所以会出现这种2:8的现象,压测过程中请求较大,故比例偏差是微乎其微的,可忽略。
  4、使用JMeter内置随机数+if控制语句来实现
  具体步骤:
  ①右击线程组→【添加】→【配置元件】→【Random Variable】→设置变量名称、随机范围。
  为每个请求添加if控制器的方法同方法三中的步骤一样,连变量名都一样,原样操作即可。
  三、各种方法的优缺点     
  1、对每个请求设置循环次数
  优点:操作简单易于实现。
  缺点:只能顺序执行,无法随机执行。
  2、通过switch controller来实现实现
  优点:可以随机执行。
  缺点:如果接口较多,比例偏差较大,设置起来比较费劲,例如2:10:88,数组里是2个0,10个1,88个2。
  因为每次都要读一遍BeanShell 取样器,严重影响性能,使结果偏离现实。
  3、通过自定义随机变量+if控制器来实现
  优点:可拓展性高,可以根据需求用脚本实现。
  缺点:学习成本高,不适宜新手。性能低,没执行一次,都要先执行下这个Java脚本。
  4、使用JMeter内置随机数+if控制语句来实现
  优点:易上手,操作简单,性能高,因为用的是JMeter内置随机数,所以比方法3性能更高一些。
  缺点:可拓展性差,不能根据特殊需求控制随机变量的随机性,只能设置一个随机区间。
  所以,根据经验,方法4是最适用大众的按比例压测的方法。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号