jmeter分布式导致重复登录的问题、以及写txt、csv、统计行数
经常收到微信好友的各种问题咨询,今天分享一个比较有代表性的,希望对大家有所帮助。
一位微信好友的提问
问题如下:
问题分析
先简单介绍下服务端的处理逻辑,关于登录,服务端的逻辑一般是:校验用户名、密码(可能还有验证码,但是压测环境都会特殊处理),成功后,会根据规则(比如拼接时间戳等字符串、加盐、加密),生成一个tokenId,然后存入redis;关于依赖登录的请求,服务端的逻辑一般是:会校验传入的tokenId在redis中是否存在,存在,表示用户已经登录ok了,否则会返回登录超时之类的信息;
我们在压测的时候,有些接口是依赖登录的,常规操作是:使用仅一次控制器,每个账号只登录一次,登录成功后,正则提取到tokenId,此时就存入了当前线程的变量中,然后把此tokenId作为被压测接口的入参;
如果是分布式,我们需要手动把登录用户名参数化文件拷贝到负载机上(注意:loadrunner是自动把脚本和参数化文件分发到负载机上),此时,多个负载机使用的参数化文件内容是相同的,分布式压测的时候,如果A负载机的某个线程先使用qzcsbj这个账号登录成功,tokenId也存入redis了,压测过程中,这个线程就会一直使用这个tokenId值,然后B负载机的某个线程也用qzcsbj这个账号登录成功,生成新的tokenId,此时会把redis里面A负载机生成的值更新,最后,A负载机上那个线程的请求都会失败,这就是这位微信好友的问题。
解决方案
方案一:各个负载机上参数化文件内容不一样,这样就需要更多的用户名;
方案二:避免登录接口的影响,我们可以先单独操作依赖的请求,把需要获取的关联值tokenId存到文件中,被压测的请求就从这个文件中获取tokenId,这样,我们压测的脚本中就不需要登录接口了,只有我们的被压测接口,有人可能会问,tokenId是有有效时间的,那是不是要频繁获取tokenId生成文件呢?当然不是,我们可以找开发帮忙把有效时间设置长点,比如24h,这样,获取一次,就可以用一天了;负载机参数化文件内容相同,如果被压测接口是修改操作,会有数据库锁等待,甚至锁等待超时的情况出现(参考这篇推文里的案例:性能测试:通过一个案例告诉你,性能到底要不要熟悉业务逻辑?);
方案三(推荐):基于方案二,各个负载机上参数化文件的内容都不同;
方案实现举例
下面简单介绍下如何将关联转换为参数化:
1、删除已存在的参数化文件tokenId.txt
注意:因为后面要生成tokenId.txt这个文件,如果这个文件存在,我们先删除。
2、生成参数化的文件tokenId.txt
这里只是演示,假设需要100个账号,线程数设置为100,循环次数设置为1,即每个线程运行一次
a.登录接口需要的csv参数化文件userInfo.dat
注意,此参数化文件中有两列,第一列是卡号,第二列是登录账号,下图抹掉了敏感数据
登录获取参数化文件中的登陆账号userAccount,而卡号cardNumber是被压测接口需要的参数
b.登录请求
正则提取tokenId
c.把关联获取到的值写入文件,因为被压测的接口需要用到tokenId和卡号cardNumber,所以需要把tokenId和卡号配对写在一行上,第一列是tokenId,第二列是卡号cardNumber
生成的tokenId.txt文件,逗号分隔同一行的tokenId和卡号cardNumber两列数据,抹掉了敏感数据
最后,如果有N个负载机,就写个脚本把tokenId.txt的内容拆分为N个文件,比如:tokenId_1.txt,tokenId_2.txt ... tokenId_N.txt,但是,复制到负载机上,文件名都要改为tokenId.txt
name、password为参数化csv文件中的值,加token写新的csv
FileWriter fstream = new FileWriter("C:\\data.csv",true); //写入数据到文件 BufferedWriter out = new BufferedWriter(fstream); // ","在csv文档中就是向右移一个单元格 out.write(vars.get("name")+","+ vars.get("password") +"," + vars.get("token")); //换行 out.write(System.getProperty("line.separator")); out.close(); fstream.close();
补充:如果值是数值,写入csv后,值用科学技术法保存了
out.write("123456789000000"+","+"123456789000000");
值前拼接\t:out.write("\t123456789000000"+","+"123456789000000");
csv行数
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; String putNum; int rowNum=0; try { BufferedReader br=new BufferedReader(new FileReader("D:\\apache-jmeter-5.1.1\\bin\\data.csv")); String tmpStr=""; while((tmpStr=br.readLine())!=null) { rowNum++; } rowNum=rowNum-1; } catch (IOException e) { e.printStackTrace(); } vars.put("putNum",String.valueOf(rowNum)); log.info("==========CSV行数:" + rowNum);
3、被压测接口脚本
被压测接口脚本略,这里只演示参数化文件这样,
这样,被压测接口就可以用上面生成的关联参数文件tokenId.txt了,下面变量名称和生成的tokenId.txt文件中变量顺序要一致
好了,就这样,是不是很简单?
如有不准之处,或者补充,请文末留言,谢谢。
更多案例:https://www.cnblogs.com/uncleyong/p/14098538.html
猜你喜欢
点击阅读☞一篇文章告诉你怎么做性能测试
点击阅读☞如何面试性能测试
点击阅读☞面试题(造火箭必备技能):请举例一个最有成就感的性能bug
点击阅读☞jmeter5.1分布式压
点击阅读☞性能测试案例:redis获取不到连接池,Timeout waiting for idle object
点击阅读☞性能测试案例:tps波动频繁
点击阅读☞性能测试案例:一个频繁fgc问题
点击阅读☞性能测试案例:获取不到redis连接池
__EOF__
关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevTestOps)、测开等
面试必备:项目实战(性能、自动化)、简历笔试,https://www.cnblogs.com/uncleyong/p/15777706.html
测试提升:从测试小白到高级测试修炼之路,https://www.cnblogs.com/uncleyong/p/10530261.html
欢迎分享:如果您觉得文章对您有帮助,欢迎转载、分享,也可以点击文章右下角【推荐】一下!