【转】性能测试分享---java vuser协议(2)---LoadRunner篇

转自:http://blog.csdn.net/weiweicao0429/article/details/8941137

LoadRunner性能测试工具使用:

1、新建脚本,选择java vuser协议。初步结构是

[java] view plaincopyprint?

  1. import lrapi.lr;
  2. public class Actions
  3. {
  4. //在init方法里面编写一个虚拟用户循环只执行一次的方法,如可以把协商写在里面,就可以达到每个用户协商一次之后,就不再协商的效果
  5. public int init() throws Throwable {
  6. return 0;
  7. }//end of init
  8. //在aciton方法里面编写需要循环并发的业务方法,如交易的方法,在run_time settings中设置循环的次数。
  9. public int action() throws Throwable {
  10. return 0;
  11. }//end of action
  12. //在end方法里面编写最后要执行的方法,如释放资源,没有可以不写。
  13. public int end() throws Throwable {
  14. return 0;
  15. }//end of end
  16. }
import lrapi.lr;
public class Actions
{

//在init方法里面编写一个虚拟用户循环只执行一次的方法,如可以把协商写在里面,就可以达到每个用户协商一次之后,就不再协商的效果
public int init() throws Throwable {
return 0;
}//end of init

//在aciton方法里面编写需要循环并发的业务方法,如交易的方法,在run_time settings中设置循环的次数。
public int action() throws Throwable {
return 0;
}//end of action

//在end方法里面编写最后要执行的方法,如释放资源,没有可以不写。
public int end() throws Throwable {
return 0;
}//end of end
}

2、在初始代码的基础上继续编写业务方法。需要注意的是:

1)把只需要创建一次对象的语句如:Random rd = new Random();放在init,aciton,end方法之外,可以避免在循环中创建很多的对象。但是需要注意的是如果是创建HTTP请求的对象是需要反复创建的,不能单提出来,否则执行一次之后,该连接被释放了,而没有创建新的连接,第二次就执行不下去了。

2、脚本编写完之后,将该脚本所有import的类的jar包放在一个文件夹下,点击Run Time Settings的classpath,把所有jar包都添加进去。

3、运行脚本,看看能不能成功执行,按照错误提示调试脚本。

4、接下来,可以把需要变化的值进行参数化。如商户名和AESKEY。选中值,右键选择replace with a parameter,在parameter list功能里添加需要用到的商户和AESKEY的值,将商户参数的循环方式select next row选择unqie,update value on选择once,表示为个商户只取唯一的值。aeskey的select next row选择same line as merchant。

5、接下来插入事物,把需要计算业务时间的代码前后都插入事物函数,如lr.start_transaction("pay");lr.end_transaction("pay", lr.AUTO);如果想更加详细的知道每一步操作的时间,可以多插入一些事物,如加密,解密,获取返回值等步骤均插入事物函数。

6、如果需要并发执行,还需要插入集合点函数lr.rendezvous("pay");这样在场景里并发执行的时候,所有的虚拟用户会等到都准备好之后在一个时间点执行。

7、接下来就是在场景里执行了。点击tools---create controller scenario。进入场景。并发10个用户执行5分钟。同时监控tomcat的日志。

在并发的情况下,出现了一些问题,下面针对这些问题给出解决方案。

遇到的问题1、在并发执行1分钟后,开始有报错,主要的报错是解密失败,同时tomcat挂了,不能在接受新的请求。

找到问题根源:通过监控tomcat日志,发现后期有很多的报错日志是文件打开过多。

严重: Socket accept failed java.net.SocketException: 打开的文件过多 at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408) at java.net.ServerSocket.implAccept(ServerSocket.java:462) at java.net.ServerSocket.accept(ServerSocket.java:430) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:352) at java.lang.Thread.run(Thread.java:662) 2013-5-16 11:38:46 org.apache.tomcat.util.net.JIoEndpoint$Acceptor run 2013-05-16 11:38:44,974 INFO [DefaultRequestDirector.java:586] - I/O exception (java.net.SocketException) caught when connecting to the target host: 打开的文件过多 2013-05-16 11:38:44,974 ERROR [CreditPay.java:167] - 信用卡支付失败 com.yibao.payapi.client.RequestApiException: 请求服务未正常返回[statuscode:404, text:<html><head><title>Apache Tomcat/6.0.29 -

解决方案:由于建立SOCKET会占用一个系统句柄,效果类似于打开了一个文件。LINUX默认的最大文件打开个数是1024(可能不同内核版本不一样),所以如果并发太多连接时就会报错。需要修改文件打开数设置。

当前设置最大打开文件数可以通过如下命令查看。    ulimit -n

这个数字说明了一个普通用户能够在一个单独会话中所能打开最大的文件数目。注意。如果是root,以下操作不能使ulimit -n的输出增加。因为用户root用户不受这个ulimit限制。只有普通用户才会受这个限制。

为了提高最大打开文件数到默认值1024以上, 需要在系统上修改2个地方。 在这个案例中, 我们将最大打开文件数增加到为65535(系统部给出的建议)。 所有的步骤需要root用户操作。

1、/etc/pam.d/login 添加 session required     /lib/security/pam_limits.so

2. 按照最大打开文件数量的需求设置系统, 并且通过检查/proc/sys/fs/file-max文件来确认最大打开文件数已经被正确设置。 echo 65535 > /proc/sys/fs/file-max

3、在/etc/security/limits.conf文件中设置最大打开文件数,添加2行内容:

* soft nofile 4096 * hard nofile 4096

解释:下面是一行提示

#<domain>      <type>  <item>         <value>添加如下这行。 * - nofile 2048 这行设置了每个用户的默认打开文件数为2048。 注意"nofile"项有两个可能的限制措施。 就是<type>项下的hard和soft。 要使修改过得最大打开文件数生效,必须对这两种限制进行设定。 如果使用"-"字符设定<type>, 则hard和soft设定会同时被设定。

硬限制表明soft限制中所能设定的最大值。 soft限制指的是当前系统生效的设置值。 hard限制值可以被普通用户降低。但是不能增加。 soft限制不能设置的比hard限制更高。 只有root用户才能够增加hard限制值。

遇到的问题2:在虚拟用户少的时候并发没有再出现文件打开过多的错误,在并发量达到30,运行时间达到3分钟的时候,有报错:HTTP-500

找到问题根源:通过查看tomcat和程序的日志,看到有大量的http-500的错误,是nginx已经拒绝了请求。

解决方案:修改nginx配置文件

vi /etc/nginx/nginx.conf

events {

worker_connections 1024;

}

调整为

events {

worker_connections 65535;

}

最后附上我写的信用卡支付的脚本:

[java] view plaincopyprint?

  1. /*
  2. * LoadRunner Java script. (Build: _build_number_)
  3. *
  4. * Script Description:
  5. *
  6. */
  7. import lrapi.lr;
  8. import http.HttpClient4;
  9. import http.HttpParameter;
  10. import http.HttpResp;
  11. import http.JsonUtil;
  12. import http.Testcredit;
  13. import org.apache.commons.httpclient.HttpClient;
  14. import org.apache.commons.httpclient.HttpException;
  15. import org.apache.commons.httpclient.methods.PostMethod;
  16. import java.util.Random;
  17. import java.util.Date;
  18. import java.text.SimpleDateFormat;
  19. import java.util.Calendar;
  20. import com.yeepay.g3.utils.common.encrypt.AES;
  21. import com.yibao.utils.des3.RSA_Encrypt;
  22. public class Actions
  23. {
  24. public String aes;
  25. Date d = new Date();
  26. Testcredit tc = new Testcredit();
  27. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  28. HttpParameter parameter = new HttpParameter();
  29. public int init() throws Throwable {
  30. String url = "http://xxxxx/xxxxx/consult";
  31. HttpClient4 client =HttpClient4.createDefault();
  32. String data = "";
  33. Calendar now = Calendar.getInstance();
  34. now.setTime(d);
  35. String dateline=format.format(now.getTime());
  36. System.out.println(dateline);
  37. Date date = format.parse(dateline);
  38. String dates=date.getTime()/1000+"";
  39. System.out.println(dates);
  40. try {
  41. data = AES.encryptToBase64(dates, "<aes>");
  42. } catch (Exception e) {
  43. e.printStackTrace();
  44. }
  45. parameter.add("data", data);
  46. parameter.add("merchantaccount", "<merchant>");
  47. HttpResp resp = new HttpResp();
  48. try{
  49. resp=client.doPost(url, parameter, "utf-8");
  50. String respStr= resp.getText("utf-8");
  51. System.out.println(respStr);
  52. aes=AES.decryptFromBase64(respStr, "<aes>");
  53. System.out.println("aes="+aes);
  54. } catch (Exception e) {
  55. e.printStackTrace();
  56. }
  57. client.shutdown();
  58. return 0;
  59. }//end of init
  60. public int action() throws Throwable {
  61. StringBuilder sb = new StringBuilder("");
  62. Random rd = new Random();
  63. for(int i=1;i<=6;i++){
  64. int sr=rd.nextInt(9);
  65. sb.append(String.valueOf(sr));
  66. }
  67. String key=sb.toString();
  68. int rds=rd.nextInt(999999);
  69. lr.start_transaction("pay");
  70. lr.rendezvous("pay");
  71. HttpClient client = new HttpClient();
  72. PostMethod method = new PostMethod("http://xxxxxxxx/xxxxxxx/api/bankcard/credit/pay");
  73. System.out.println(aes);
  74. String PUBLIC_KEY=aes;
  75. System.out.println("PUBLIC_KEY"+PUBLIC_KEY);
  76. String encryptkey = "0123456789"+key;
  77. String merchantAccount = "<merchant>";
  78. //民生
  79. String cardNo = "6XXXXXXXXXXXXXX";
  80. String validthru = "XXXX";
  81. String cvv2 = "XXX";
  82. String phone = "13466745431";
  83. String orderId = rds+"334234223"+key;
  84. System.out.println(orderId);
  85. Integer transtime = (int)(System.currentTimeMillis()/1000);
  86. Integer currency = 156;
  87. String amount = "50";
  88. String productcatalog = "1";
  89. String productName = "123";
  90. String productDesc = "小丸子";
  91. String userIp = "123.45.45.45";
  92. String identityId = "a";
  93. Integer identityType = 6;
  94. String other = "eeee";
  95. String data = "{\"merchantaccount\":\"" + merchantAccount
  96. +"\",\"cardno\":\"" + cardNo
  97. + "\",\"validthru\":\"" + validthru
  98. + "\",\"cvv2\":\"" + cvv2
  99. + "\",\"phone\":\"" + phone
  100. + "\",\"orderid\":\"" + orderId
  101. + "\",\"transtime\":" + transtime
  102. + ",\"currency\":" + currency
  103. + ",\"amount\":" + amount
  104. + ",\"productcatalog\":\"" + productcatalog
  105. + "\",\"productname\":\"" + productName
  106. + "\",\"productdesc\":\"" + productDesc
  107. + "\",\"userip\":\"" + userIp
  108. + "\",\"identityid\":\"" + identityId
  109. + "\",\"identitytype\":" + identityType
  110. + ",\"other\":\"" + other + "\"}";
  111. data = AES.encryptToBase64(data, encryptkey);
  112. try {
  113. method.setParameter("merchantaccount", merchantAccount);
  114. method.setParameter("data", data);
  115. method.setParameter("encryptkey", RSA_Encrypt.encrypt(encryptkey, PUBLIC_KEY));
  116. client.executeMethod(method);
  117. System.out.println(method.getStatusLine());
  118. String respStr = method.getResponseBodyAsString();
  119. System.out.println(respStr);
  120. String result = AES.decryptFromBase64(respStr, encryptkey);
  121. System.out.println(result);
  122. method.releaseConnection();
  123. } catch (Exception e) {
  124. // TODO Auto-generated catch block
  125. e.printStackTrace();}
  126. lr.end_transaction("pay", lr.AUTO);
  127. return 0;
  128. }//end of action
  129. public int end() throws Throwable {
  130. return 0;
  131. }//end of end
  132. }
时间: 2024-11-07 16:28:17

【转】性能测试分享---java vuser协议(2)---LoadRunner篇的相关文章

LoadRunner JAVA Vuser协议手工写脚本Failed to find Classes.zip entry in Classpath问题 .

JAVA Vuser协议手工写脚本Failed to find Classes.zip entry in Classpath问题解决方法: 前提条件: 环境变量:正确的配置了JAVA_HOME,path正确的指明了JAVA_HOME的bin路径和LR的bin路径,classpath中指明了jdk的lib路径和LR的lib路径. 当前LoadRunner的版本是9.0版. 当前的JDK版本是1.7. 一.错误内容如下: 通知: Found jdk version: 1.7.0. [MsgId: M

java vuser协议

一. 项目流程 登录-->修改支付密码-->下订单-->支付订单-->查看订单列表 支付密码:md5进行加密算法. 1. 为什么要学习java vuser协议? 为了解决工作中需要调用开发的算法,进行脚本的开发 2. 工作中会遇到:需要对支付密码进行md5算法的调用,以及更复杂的情况(实际项目中可能使用sign + 每次请求的,再请求到服务器,这样做的好处:不容易被攻击和破解) 3. 不懂java代码,怎么解决? 可以先学会思路,按照步骤一步一步解决 二. 步骤 1. 搭建jdk环

【转】性能测试分享---java协议(1)------jemter篇

转自:http://blog.csdn.net/weiweicao0429/article/details/8941081 主要用到了两个性能测试工具,一个是jmeter,一个是LoadRunner. 使用jmeter的测试方法: 1.下载jemeter的linux版本的,下载的文件里包含了两个jar包,一个是ApacheJMeter_core.jar,ApacheJMter_java.jar.分别把这两个jar放到eclipse的Java Build Path的libraries下面. 2.创

Loadrunner 11 中的Java Vuser

Java vuser是自定义的java虚拟用户脚本,脚本中可以使用标准的java语言. 1.安装jdk 注意,lr11最高支持jdk1.6 2.配置环境变量 3.在lr中选择java vuser协议 脚本结构设计原则: 在init中编写初始化脚本 在action中编写业务流程 在end中编写释放资源等收尾操作 适用范围: 1.不适合录制的业务功能点性能测试,如视频播放,http文件下载等. 2.利用java语言开发的应用系统

Java Vuser虚拟用户

Java Vuser是自定义的Java虚拟脚本,脚本中可以使用标准的Java语言. 环境配置 1.安装jdk 注意:LR11最高支持1.6 2.配置Java环境变量 3.在lr中选择Java Vuser 协议 脚本结构 一般在init中编写初始化脚本,在action中编写业务流程,在end编写释放资源的内容 适用范围: 1)不太适合录制的业务功能点性能测试,如视频播放.http文件下载 2)利用Java语言开发的应用系统.

LR之Java Vuser

虽然LR对C有较好的支持,但有时使用Java Vuser会更方便,以下描述通过LR来编写Java脚本以及调用jar包的基本步骤. 1.安装配置java环境  LR的java vuser脚本的执行依赖于脚本所在机器的java环境,LR并没有独立java运行环境,因此首先要在Vugen所在机器上安装java环境.特别注意:LR的不同版本对于JDK版本的支持是不同的. 环境说明: LoadRunner11:安装路径:C:\Program Files\HP\LoadRunner 平台:windows 7

【原创】LoadRunner Java Vuser脚本的配置和调试指南

1 编写目的 本文介绍了Loadrunner多负载压力机的配置,并通过测试Java Vuser的数据库连接脚本对配置结果进行了验证,同时对配置过程中遇到的问题和解决的过程进行了记录,关于Java数据库编程的深入学习,大家可以参考其他Java相关教程. 文中的内容大部分来源于本人工作中解决问题的实际经验,另一部分来源于网络,所有内容本人都亲自验证,但难免有疏漏之处,如有疑问,请大家不吝赐教. 文中Loadrunner版本为9.5,操作系统类型为Windows XP和Windows 2003 Ser

如何解决java协议的loadrunner脚本返回字符串乱码问题

在编写java协议的loadrunner脚本时,服务器偶尔会返回部分中文字符,这部分字符在日志中直接打印时显示的是乱码,需要进行转义才行.原因是实际返回的字符时UTF-8格式,但是loadrunner中使用的是GB2312格式,使用String的构造函数 String(byte b[],"encoding")进行两次转码即可. 下面是代码: web.reg_save_param("msg", new String[]{ "NOTFOUND=ERROR&qu

JAVA VUser

一.java虚拟用户协议 java虚拟用户脚本主要有Java Vuser.Corba-Java.RMI-Java.EJB等类型.这些类型的虚拟用户脚本均可以用java语言来手工编写. 1. Java Vuser:子定义的Java虚拟用户脚本,脚本中可以使用标准的Java语言.这种虚拟用户不可以录制,只能采用纯手工编写,其适用范围和C Vuser一样. 2. Corba-Java:用来测试用java编写的使用corba应用程序or小程序的性能,用户可以先运行VuGen录制脚本,然后使用标准的Jav