1.背景

最近宝路遇到个项目,在使用JMeter过程中引发了一些思考,宝路尝试用各种方式去验证,进而有了今天“JMeter原子性”相关主题。

2.目的

探究JMeter的事务的原子性

3.实战

说道原子性,有的同学还一头雾水。。。。啥是原子性?相信大家应该都接触过数据库,数据库的事务就具有原子性(其余的几个特性本次不讨论),宝路觉得这个原子性的概念,更像是从化学这么学科中“偷”过来的。在化学中,原子是在化学反应不可再分的微粒。影射到事务,那就是一个或者多个操作步骤组成了一个原子单元,在事务执行过程中,如果其中任意一个操作步骤失败,那么整个事务即失败。

说下本次JMeter的测试计划,本次设计4个接口,“登录”、“活动信息”、“查卡列表”、“查询余额”,只有登录成功之后才会触发其余交易。

脚本结构(全部交易默认成功):

脚本中sampler都用相同代码来模拟,可以通过random参数控制返回内容,sleep参数控制交易耗时。

  1. public class JMeterTransaction extends AbstractJavaSamplerClient {

  2. @Override
  3. public Arguments getDefaultParameters() {
  4. Arguments arguments = new Arguments();
  5. arguments.addArgument("random","1");
  6. arguments.addArgument("sleep","50");
  7. return arguments;
  8. }

  9. @Override
  10. public SampleResult runTest(JavaSamplerContext arg0) {
  11. SampleResult result = new SampleResult();
  12. result.sampleStart();
  13. String random = arg0.getParameter("random");
  14. long sleep = Long.valueOf(arg0.getParameter("sleep"));
  15. try {
  16. TimeUnit.MILLISECONDS.sleep(sleep);
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. result.setSuccessful(true);
  21. result.setResponseCodeOK();
  22. result.setResponseData(random,"UTF-8");
  23. result.sampleEnd();
  24. return result;
  25. }
  26. }

10并发执行1min结果:

嗯?各接口样本数为什么不一样?有点意思?理论上每个接口样本数应该一致啊。。。。。

宝路调整了下事务控制器配置,勾选了Genernate parent sampler

10并发执行1min结果:

感觉目前没啥问题,宝路将执行过程中的结果保存了,打开本次jtl结果:

嗯?如出一辙。。。从目前看与事务原子性,登录成功多少笔,其余的交易就应该成功多少笔。目前能看JMeter的事务控制不符合原子性,难道是我使用的姿势有问题?

多次执行过,宝路发现个共性:同一个测试计划的各接口的样本总数是递减的。所以宝路做了推测:在场景停止时(线程数从某个设定的值下降到0),比如某个线程在执行完“查询卡列表”时,线程就被kill了,进而导致“查询余额”接口没被执行。

宝路又做了验证:

不勾选事务控制器Genernate parent sampler

勾选事务控制器Genernate parent sampler

清除结果后,使用聚合报告打开本次执行的jtl结果:

经过多次执行,发了个诡异现象:在不勾选Genernate parent sampler时,事务控制器统计的样本数与最后一个接口统计的样本数相同,在勾选Genernate parent sampler时,事务控制器统计的样本数与首个接口统计的样本数相同。

先不管这个是不是BUG,从事务角度看不满足原子性。单纯的事务控制器并不严格的具备原子性,这是目前看到的表像。

那么怎么解决呢?宝路之前写过一篇关于JavaRequest探究的文章,感兴趣的同学可以点击看下。本文就不过多阐述了。直接看结果

清除聚合报告数据后,再打开本次执行的jtl结果文件

嗯,真香。目前觉得唯一的缺点就是没有一个能监听subResult的插件。相同的场景,都是基于java请求的编写的底层脚本,唯一的区别就是组织方式不同。

其实你完全可以这样看:把TestJavaLee中的main看成事务控制器,你细细品,再细细品。。。。

进而宝路得出:单纯用事务控制器来组织多个sampler,严格来说不具有事务的原子性。

如果有不同想法或者看法,欢迎给宝路留言,最后附下TestJavaLee代码:

  1. public class TestJavaLee extends AbstractJavaSamplerClient {
  2. @Override
  3. public Arguments getDefaultParameters() {
  4. Arguments arguments = new Arguments();
  5. arguments.addArgument("subResult","RAW_NO");
  6. return arguments;
  7. }

  8. @Override
  9. public SampleResult runTest(JavaSamplerContext arg0) {
  10. SampleResult main = new SampleResult();
  11. main.setSampleLabel("Main事务");
  12. main.sampleStart();

  13. SampleResult sample_a = new SampleResult();
  14. sample_a.setSampleLabel("登录");
  15. sample_a.sampleStart();
  16. try {
  17. TimeUnit.MILLISECONDS.sleep(50);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. sample_a.sampleEnd();
  22. sample_a.setSuccessful(true);
  23. main.addSubResult(sample_a,false);

  24. SampleResult sample_b = new SampleResult();
  25. sample_b.setSampleLabel("活动信息");
  26. sample_b.sampleStart();
  27. try {
  28. TimeUnit.MILLISECONDS.sleep(70);
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. sample_b.sampleEnd();
  33. sample_b.setSuccessful(true);
  34. main.addSubResult(sample_b,false);

  35. SampleResult sample_c = new SampleResult();
  36. sample_c.setSampleLabel("查卡列表");
  37. sample_c.sampleStart();
  38. try {
  39. TimeUnit.MILLISECONDS.sleep(80);
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. sample_c.sampleEnd();
  44. sample_c.setSuccessful(true);

  45. main.addSubResult(sample_c,false);

  46. SampleResult sample_d = new SampleResult();
  47. sample_d.setSampleLabel("查询余额");
  48. sample_d.sampleStart();
  49. try {
  50. TimeUnit.MILLISECONDS.sleep(100);
  51. } catch (InterruptedException e) {
  52. e.printStackTrace();
  53. }
  54. sample_d.sampleEnd();
  55. sample_d.setSuccessful(true);

  56. main.addSubResult(sample_d,false);

  57. main.setSuccessful(true);
  58. return main;
  59. }

  60. }

关于JMeter原子性相关探究的更多相关文章

  1. 关于自定义tabBar时修改系统自带tabBarItem属性造成的按钮顺序错乱的问题相关探究

      关于自定义tabBar时修改系统自带tabBarItem属性造成的按钮顺序错乱的问题相关探究 测试代码:http://git.oschina.net/Xiyue/TabBarItem_TEST 简 ...

  2. Jmeter+Badboy实战经验三 Jmeter关联相关知识

    1. 什么时候需要使用关联? 有些参数是动态变化的,获取之后,再次操作的时候,参数的值已经发生了变化,这种情况下就会出现脚本不可运行的问题,就需要用到了关联 2. 关联是什么概念? 3.jmeter ...

  3. JMeter的JavaRequest探究

    1.背景 最近笔者的一位老朋友咨询了一个问题:在自定义的Java请求中如何编写多个请求?老朋友反应他们发送请求只能基于这种Java请求形式(代码调需用三方封装的jar包).这个问题恰巧不久前在笔者所在 ...

  4. ${__setProperty 等常见jmeter参数相关博客汇总

    jmeter 控制线程组执行顺序   这个要配合全局变量.if和while来实现BeanShell取样器,全局变量:${__setProperty(newswitch,${switch1},)}if条 ...

  5. 性能测试之--Apache JMeter安装

    Hi,今天给大家分享一下安装JMeter的相关内容~ Apache JMeter 是Apache组织的开源项目,是一个100%纯Java桌面应用,用于压力测试和性能测试. 它能够对HTTP.FTP服务 ...

  6. 【转】jmeter 进行java request测试

    本周使用jmeter进行一个远程dubbo接口的性能测试,因为没有访问页面,本来开发可以写一个页面,进行http请求的调用,不过已经看到jmeter可以直接对java request进行测试,所以尝试 ...

  7. iOS-事务相关

    事务管理 事务(Transaction):1.构成单一逻辑工作单元的操作集合DBMS中的用户程序DBMS外的可执行程序对数据库的读/写操作序列2.读从数据库中读取数据,首先从磁盘中读到内存(Buffe ...

  8. 使用Jmeter至WebService压力测试

    使用Jmeter至WebService压力测试   目中我们使用了Jmeter对webservice进行了压力測试,Apache JMeter是Apache组织开发的基于Java的压力測试工具.用于对 ...

  9. 转:Jmeter以non-gui模式进行分布式测试

    由于Jmeter是一个纯JAVA的应用,用GUI模式运行压力测试时,对客户端的资源消耗是相当惊人的,所以在进行正式的压测时一定要使用non-gui模式运行,如果并发数很高或者客户端的硬件资源比较一般的 ...

随机推荐

  1. Python环境的搭建(windows系统)

    1.首先访问http://www.python.org/download/去下载最新的python版本. 2.安装下载包,一路next. 3.为计算机添加安装目录搭到环境变量,如图把python的安装 ...

  2. spring cloud 2.x版本 Eureka Server服务注册中心教程

    本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 1.创建服务注册中心 1.1 新建Spring boot工程:eureka-server 1 ...

  3. CSP2019游记

    第一轮 Day 0 今天正好学校开运动会,就从开幕式开始翘,申请来机房训练. 早上六点多到了机房. 然后果不其然,运动会又下雨了(祈雨大会).机房冷的一批. 今天中午没有午休时间,去食堂吃个饭就直接来 ...

  4. Numpy 中的比较和 Fancy Indexing

    # 导包 import numpy as np Fancy Indexing 应用在一维数组 x = np.arange(16) x[3] x[3:9] # array([3, 4, 5, 6, 7, ...

  5. [AspNetCore 3.0 ] Blazor 服务端组件 Render, RenderFragment ,RenderTreeBuilder, CascadingValue/CascadingParameter 等等

    一.组件 支撑Blazor的是微软的两大成熟技术,Razor模板和SignalR,两者的交汇点就是组件.通常,我们从ComponentBase派生的类型,或者创建的.razor 文件,就可以称作组件. ...

  6. 大数据之路day01_1--Java下载、安装等配置

    从今天开始,我就正式的走上大数据的道路了,如果说我为啥要去学习大数据,可能我的初衷是以后可以接触到人工智能方面的技术,后来在自学的过程中发现,学习人工智能,需要扎实的算法,以及对大量数据的处理,再者, ...

  7. IntelliJ IDEA 中设置左菜单字体, 编辑器字体和控制台的字体

    IntelliJ IDEA 中设置左菜单字体大小 File-Settings,然后选择appearance,下图右侧红色边框中的内容即设置菜单的字体和大小 ​ IntelliJ IDEA 中设置当前编 ...

  8. 底半部之工作队列和tasklet,内核定时器。

    1.软中断机制  不能以模块形式出现   使用起来不够灵活2.tasklet  核心数据结构       struct tasklet_struct      {          function  ...

  9. 怎么把CAT客户端的RootMessageId记录到每条日志中?

    什么是RootMessageId? 为了理解RootMessageId先简单介绍一下CAT的数据结构设计.CAT客户端会将所有消息都封装为一个完整的消息树(MessageTree),消息树可能包括Tr ...

  10. PHPExcel数据导入(含图片)

    PHPExcel是一个PHP类库,用来帮助我们简单.高效实现从Excel读取Excel的数据和导出数据到Excel. 首先下载压缩包: https://codeload.github.com/PHPO ...