暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【松勤软件性能测试】如何利用LoadRunner最高效的批量制造MySQL数据

松勤软件学院 2018-01-20
307

批量制造数据的方法有很多种,也有许多专业的工具,但是都算不上高效,针对MySQL的批量插入数据,目前认为最高效的方式是通过执行JAVA代码(通过设置事务为非自动提交,以executeBatch批处理提交大量插入事务)来实现,但是JAVA的灵活参数化和大用户量分布式并发执行,绝对没有LoadRunner方便。


所以我们可以利用LoadRunner+JAVA的方式,来实现高效、高可靠、持续性的批量造数据,既利用LoadRunner的Java_Vuser:

1、在loadrunner中新建脚本(本文以LoadRunner11为例),要求选择协议类型为Java->Java Vuser

2、在Run-time Settings设置JDK路径,由于LoadRunner11不支持jdk1.8,所以推荐引用jdk1.6

3、需要mysql的java驱动,可以到MySQL官网下载"mysql-connector-Java",并通过Run-time Settings引用JAR包



4、在Java Vuser输入以下样例代码:

[java] view plain copy

  1. /*

  2.  * LoadRunner Java script. (Build: _build_number_)

  3.  * 

  4.  * Script Description: 

  5.  *                     

  6.  */

  7. import lrapi.lr;  

  8. import java.beans.Statement;    

  9. import java.sql.Connection;    

  10. import java.sql.DriverManager;    

  11. import java.sql.PreparedStatement;    

  12. import java.sql.ResultSet;    

  13. import java.sql.SQLException;   

  14. public class Actions  

  15. {  

  16.     private Connection conn = null;    

  17.     PreparedStatement statement = null;  

  18. // connect to MySQL  

  19.     void connSQL() {    

  20.         String url = "jdbc:mysql://172.16.1.67:3306/test?characterEncoding=UTF-8";    

  21.         String username = "root";    

  22.         String password = "123456"// 加载驱动程序以连接数据库     

  23.         try {     

  24.             Class.forName("com.mysql.jdbc.Driver" );     

  25.             conn = DriverManager.getConnection( url,username, password );     

  26.             }    

  27. //捕获加载驱动程序异常  

  28.          catch ( ClassNotFoundException cnfex ) {    

  29.              System.err.println(    

  30.              "装载 JDBC/ODBC 驱动程序失败。" );    

  31.              cnfex.printStackTrace();     

  32.          }     

  33. //捕获连接数据库异常  

  34.          catch ( SQLException sqlex ) {    

  35.              System.err.println( "无法连接数据库" );    

  36.              sqlex.printStackTrace();     

  37.          }    

  38.     }    

  39. // disconnect to MySQL  

  40.     void deconnSQL() {    

  41.         try {    

  42.             if (conn != null)    

  43.                 conn.close();    

  44.         } catch (Exception e) {    

  45.             System.out.println("关闭数据库问题 :");    

  46.             e.printStackTrace();    

  47.         }    

  48.     }   

  49.     public int init() throws Throwable {  

  50.         connSQL();  

  51.         return 0;  

  52.     }//end of init  

  53.     public int action() throws Throwable {  

  54.         String sql = "insert into MySqlTest(ID, DataName, InsertTime, UpdateTime, DataType,DataSet) values(REPLACE(uuid(), '-', ''),?,now(),null,1,'LoadRunner')";  

  55.             conn.setAutoCommit(false);  

  56.         statement = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);  

  57.         lr.start_transaction("Insert");  

  58.         for(int i=0;i<1000;i++){//每1000条记录为一组事务,每个虚拟用户至少执行一组批量插入事务  

  59.                 statement.setString(1,"Test-A2B-<RadParam>");//用LoadRunner的方式设置随机数参数  

  60.                 statement.addBatch();  

  61.         }  

  62.         statement.executeBatch();  

  63.             conn.commit();  

  64.         lr.end_transaction("Insert", lr.AUTO);  

  65.         return 0;  

  66.     }//end of action  

  67.     public int end() throws Throwable {  

  68.         deconnSQL();  

  69.         return 0;  

  70.     }//end of end  

  71. }  


5、将以上脚本放到Loadrunner中执行(场景设置100用户,每个用户只执行一次,同时执行,这样就确保只插入10万条记录),经过测试,发现最多16秒就完成10万条记录的插入(平均执行的时间是11.658秒)。


6、也可以将for循环去掉,通过loadrunner的action循环1000次来实现



但是这样改变后速度要比用for循环慢多了,经过测试发现插入10万条数据,需要33秒(平均执行一次action是0.027秒),为什么呢,仔细对照就发现是因为action里包括了conn.commit(),也就是说每次循环都执行事务提交,批量1000条插入变成了单条插入。把脚本改动一下:

[java] view plain copy

  1. public int init() throws Throwable {  

  2.     connSQL();  

  3.     String sql = "insert into MySqlTest(ID, DataName, InsertTime, UpdateTime, DataType,DataSet) values(REPLACE(uuid(), '-', ''),?,now(),null,1,'LoadRunner')";  

  4.     conn.setAutoCommit(false);  

  5.     statement = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);  

  6.     return 0;  

  7. }//end of init  

  8. public int action() throws Throwable {      

  9.     lr.start_transaction("action");  

  10.                statement.setString(1,"Test-A2B-<RadParam>");     

  11.                statement.addBatch();      

  12.     lr.end_transaction("action", lr.AUTO);  

  13.     return 0;  

  14. }//end of action  

  15. public int end() throws Throwable {  

  16.     statement.executeBatch();  

  17.     conn.commit();  

  18.     deconnSQL();  

  19.     return 0;  

  20. }//end of end  


这么一改动,就把prepareStatement和commit都放到循环action之外,相当于一个用户执行完1000条预插入记录后,才进行commit提交,速度立马提高,经过测试,10万条记录批量insert只要15秒(平均执行一次action是0.001秒)。


7、如果要插入更多的数据,只需要用更多的用户和执行更长的并发时间就能轻松实现,而且参数化方便,如果单台压力机承受不了,还可以分布式部署多台压力机。

教育领先品牌
打造中国互联网
专注IT在线教育
以工匠精神
愿景
松勤软件

松勤网:www.songqinnet.com

微信公众号:松勤软件学院

软件测试交流QQ群:64207188

软件自动化测试QQ群:398140461

软件性能测试交流QQ群:348074292

文章转载自松勤软件学院,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论