性能测试工具操作数据库(九)-Loadrunner与MongoDB

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: Loadrunner使用JavaVuser连接mongoDB需要mongo-java-driver-2.13.3.jar
版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问我的博客 https://blog.csdn.net/smooth00/article/details/72820911

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

2、在Run-time Settings设置JDK路径,由于LoadRunner11不支持jdk1.8,本次测试是拷贝了一份低版本的JDK1.6,所以路径选择固定路径模式,如下所示:


3、上网下载一份MongoDB的JAR包(注意以下脚本是在版本为2.*的JAR包上调试通过,不保证在3.*或更高版本中能够运行),下载地址:http://central.maven.org/maven2/org/mongodb/mongo-java-driver/2.13.3/mongo-java-driver-2.13.3.jar,放到include目录下,并在Run-time Settings中配置Classpath


4、在Java Vuser脚本中编写MongoDB的增、删、改、查操作:

/*
 * LoadRunner Java script. (Build: _build_number_)
 * 
 * Script Description:                     
 */
import lrapi.lr;
import java.net.UnknownHostException; 
import java.util.ArrayList;
import java.util.List;  
  
import org.bson.types.ObjectId;  
  
import com.mongodb.BasicDBObject;  
import com.mongodb.DB;  
import com.mongodb.DBCollection;  
import com.mongodb.DBCursor;  
import com.mongodb.DBObject;  
import com.mongodb.Mongo;  
import com.mongodb.MongoException;

public class Actions
{
        //1.建立一个Mongo的数据库连接对象  
	static Mongo conn = null;  
	//2.创建相关数据库的连接  
	static DB db = null;
        /** 
	* 为相应的集合添加数据 
	* @param dbs 
	* @param collName 
	*/  
	public void insert(DBObject dbs,String collName){  
	    //1.得到集合  
	    DBCollection coll = db.getCollection(collName);  
	    //2.插入操作  
	    coll.insert(dbs);  
	}  
	/** 
	* 为集合批量插入数据 
	* @param dbses 
	* @param collName 
	*/  
	public void insertBatch(List<DBObject> dbList,String collName){  
	    //1.得到集合  
	    DBCollection coll = db.getCollection(collName);  
	    //2.插入操作  
	    coll.insert(dbList);  
	}  
	/** 
	* 根据id删除数据 
	* @param id 
	* @param collName 
	* @return 返回影响的数据条数 
	*/  
	public int deleteById(String id,String collName){  
	    //1.得到集合  
	    DBCollection coll = db.getCollection(collName);  
	    DBObject dbs = new BasicDBObject("_id", new ObjectId(id));  
	    int count = coll.remove(dbs).getN();  
	    return count;  
	}  
	/** 
	* 根据条件删除数据 
	* @param id 
	* @param collName 
	* @return 返回影响的数据条数 
	*/   
	public int deleteByDbs(DBObject dbs,String collName){  
	    //1.得到集合  
	    DBCollection coll = db.getCollection(collName);  
	    int count = coll.remove(dbs).getN();  
	    return count;  
	}  
	/** 
	 * 更新数据 
	* @param find 查询器 
	* @param update 更新器 
        * @param upsert 更新或插入(设为ture,若所更新的数据没有则插入)
	* @param multi 是否批量更新 
	* @param collName 集合名称 
	* @return 返回影响的数据条数 
	*/  
	public int update(DBObject find,  
        	DBObject update,  
       		boolean upsert,  
       		boolean multi,  
        	String collName){  
	    		//1.得到集合  
	    		DBCollection coll = db.getCollection(collName);  
	    		int count = coll.update(find, update, upsert, multi).getN();  
	    		return count;  
		}
        /** 
	* 查询器(分页) 
	* @param ref 
	* @param keys 
	* @param start 
	* @param limit 
	* @return 
	*/  
	public DBCursor find(DBObject ref,   
        	DBObject keys,  
        	int start,  
        	int limit,  
        	String collName){  
			DBCursor cur = find(ref, keys, collName);  
			return cur.limit(limit).skip(start);  
		}  
	/** 
	* 查询器(不分页) 
	* @param ref 
	* @param keys 
	* @param start 
	* @param limit 
	* @param collName 
	* @return 
	*/  
	public DBCursor find(DBObject ref,  
        	DBObject keys,  
        	String collName){  
			//1.得到集合  
			DBCollection coll = db.getCollection(collName);  
			DBCursor cur = coll.find(ref, keys);  
			return cur;  
		}

	public int init() throws Throwable {
		conn = new Mongo("172.16.1.238",27017); 
		db = conn.getDB("test");
		return 0;
	}//end of init

	public int action() throws Throwable {
		//DBCollection coll = db.getCollection("testCollection");

	    lr.start_transaction("插入操作");
		List<DBObject> dbList = new ArrayList<DBObject>();
		BasicDBObject doc = new BasicDBObject("DataName", "MongoDB-<RadNum><RadNum2>").
                              append("DataType", 1).
                              append("remark", "From Loadrunner").
                              append("Date", new BasicDBObject("InsertTime", "<getTime>").append("UpdateTime", null));
                              dbList.add(doc);

		BasicDBObject doc2 = new BasicDBObject();  
			      doc2.put("name", "小张");  
			      doc2.put("age", 25);  
			      doc2.put("address", "江苏苏州");  
			      dbList.add(doc2); 
		//2.插入操作  
		//coll.insert(dbList);
		insertBatch(dbList,"testCollection");
	    lr.end_transaction("插入操作", lr.AUTO);

	    lr.start_transaction("删除操作");
		//BasicDBObject dbs = new BasicDBObject("DataName", "MongoDB-1964905.821");
		BasicDBObject dbs = new BasicDBObject();
		dbs.put("DataName", "MongoDB-1964905.821");
		int dels=deleteByDbs(dbs,"testCollection");
		//System.out.println("删除的条数:"+dels);
		lr.log_message("删除的条数:"+dels);
	    lr.end_transaction("删除操作", lr.AUTO);

	    lr.start_transaction("更新操作");
		DBObject updateCondition=new BasicDBObject();  
          
		//where name='小张'  
		updateCondition.put("name", "小张");  
          
		DBObject updatedValue=new BasicDBObject();  
		updatedValue.put("age", 28);  
		updatedValue.put("address", "吉林长春");  
          
		DBObject updateSetValue=new BasicDBObject("$set",updatedValue);
		/** 
		* update insert_test set age=28 and address="吉林长春" where name="小张"
		* updateCondition:更新条件 
		* updateSetValue:设置的新值 
		*/
		int upds=update(updateCondition, updateSetValue, true, true,"testCollection");
		lr.log_message("更新的条数:"+upds);
	    lr.end_transaction("更新操作", lr.AUTO);

	    lr.start_transaction("查询操作");
		DBObject ref=new BasicDBObject();  
          
		//1、查询出年龄大于25岁并且小于65岁     
		ref.put("age", new BasicDBObject("$gte",25));  
		ref.put("age", new BasicDBObject("$lte",65));  
          
		DBCursor cursor=find(ref,null,1,4,"testCollection");//查询获取第2条开始的4条记录
                while (cursor.hasNext()) {  
		    DBObject object = cursor.next();  
		    System.out.print(object.get("name")+"-->");  
		    System.out.print(object.get("age")+"-->");  
		    System.out.println(object.get("address"));  
		}

		//2、查询出testCollection集合中的name和age
                DBObject keys = new BasicDBObject();  
		keys.put("_id", false);  
		keys.put("name", true);  
		keys.put("age", true);  
		DBCursor cursor2 = find(null, keys, "testCollection"); 
		while (cursor2.hasNext()) {  
		    DBObject object = cursor2.next();  
		    System.out.println(object.get("name"));  
		} 

	    lr.end_transaction("查询操作", lr.AUTO);

		return 0;
	}//end of action

	public int end() throws Throwable {
		conn.close();//关闭数据库连接
		db=null;
		conn=null;//回收资源
		return 0;
	}//end of end
}

5、运行脚本,输出正确的操作结果

注意:对于loadrnner脚本要通过Load Generators进行分布式测试时,请确保各负载压力机的JDK和Classpath路径都能够正确调用(需要保持相同的路径)。

另外需要说明的是:2.10.0版本开始引入了MongoClient类,同时在其API中也说明了Mongo类会在将来的版本中被MongoClient替换(Note: This class has been superseded by MongoClient, and may be deprecated in a future release.)。以上MongoDB连接用的还是Mongo类,所以代码仅供大家参考而已,实际项目测试还是建议采用MongoClient,否则在高并发情况下可能容易出现性能问题或其他异常问题。

由于出于线程安全等考虑,MongoDB Java从3.0开始已经打算废弃DB开头的类的使用,所以整体调用上有了较大的区别。以下提供了在3.4.2版本中测试通过的代码,以供大家参考(相当于对上面测试代码的重构)

/*
 * LoadRunner Java script. (Build: _build_number_)
 * 
 * Script Description: 
 *                     
 */
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import org.bson.types.ObjectId;

import lrapi.lr;

public class Actions
{
    //1.建立一个Mongo的数据库连接对象   
    static MongoClient mongoClient = null;
    //2.创建相关数据库的连接  
    static MongoDatabase mongoDatabase = null;
    //3.连接集合
    static MongoCollection<Document> mongoCollection = null;

    /*连接数据库*/
    public void connection(String connIP,int port,String dataName){
        //连接到服务
        mongoClient = new MongoClient(connIP,port);
        //连接到数据库  
        mongoDatabase = mongoClient.getDatabase(dataName);
            
	}
  /** 
	* 为相应的集合添加数据 
	* @param doc 
	* @param collName 
	*/  
	public void insert(Document doc,String collName){ 
			try { 
                //获取集合 参数为“集合名称”  
                mongoCollection = mongoDatabase.getCollection(collName); 
                List<Document> documents = new ArrayList<Document>();  
                documents.add(doc);
                //2.插入操作  
                mongoCollection.insertMany(documents);
			} catch (Exception e) {  
                System.err.println( e.getClass().getName() + ": " + e.getMessage() );  
			}
	}
	/*批量添加数据*/
	public void insertBatch(List<Document> docs,String collName){
       try { 
                //获取集合 参数为“集合名称”  
            mongoCollection = mongoDatabase.getCollection(collName); 
                //2.批量插入操作  
            mongoCollection.insertMany(docs);
       } catch (Exception e) {  
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );  
      }
	}
	/** 
	* 根据数据条件删除数据
  * @param key
  * @param keyValue
	* @param collName 
	*/  
	public void deleteByDbs(String key,Object keyValue,String collName){
      try { 
            //获取集合 参数为“集合名称”  
            mongoCollection = mongoDatabase.getCollection(collName); 
            //long cnt = mongoCollection.count(Filters.eq(key, keyValue));//统计删除的记录数
            //System.out.println("删除的记录数:"+cnt);
            //删除所有符合条件的文档  
           	mongoCollection.deleteMany(Filters.eq(key, keyValue));
						//mongoCollection.deleteMany(Filters.ne("",""));//清空测试数据
            //检索查看结果  
            /*FindIterable<Document> findIterable = mongoCollection.find();  
            MongoCursor<Document> mongoCursor = findIterable.iterator();  
            while(mongoCursor.hasNext()){
                System.out.println(mongoCursor.next());  
            }*/
       } catch (Exception e) {
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );  
       }
              
	}  
	
	/** 
	* 更新数据 
  * @param key 过滤参数
  * @param value 过滤参数对应值
	* @param update 更新器 
	* @param collName 集合名称 
	*/
	public void update(String key,Object value,
                        Document update,    
                        String collName){  
       try {
                //1.得到集合  
                mongoCollection = mongoDatabase.getCollection(collName);  
                //更新文档将文档中key=value的文档修改
                mongoCollection.updateMany(Filters.eq(key, value), update);  
                //检索查看结果  
                /*FindIterable<Document> findIterable = mongoCollection.find();  
                MongoCursor<Document> mongoCursor = findIterable.iterator();  
                while(mongoCursor.hasNext()){  
                    System.out.println(mongoCursor.next());  
                }*/
                //long cnt = mongoCollection.count(Filters.eq(key, value));//统计更新的记录数
                //System.out.println("更新的记录数:"+cnt);
        } catch (Exception e) {  
                System.err.println( e.getClass().getName() + ": " + e.getMessage() );  
        }
	}
	/** 
	* 查询器 
	* @param ref 
	* @param keys 
	* @param start 
	* @param limit 
	* @return 
	*/  
	public void find(Document ref,   
            Document keys,  
            int start,  
            int limit,  
            String collName){ 
     try {
         	//1.得到集合  
         	mongoCollection = mongoDatabase.getCollection(collName);     
         	//按id倒序排,跳过前m条(0-m),返回n条。
         	FindIterable<Document> findIterable = mongoCollection.find(ref).sort(new Document("_id",-1)).skip(start).limit(limit);
         	//检索查看结果
         	MongoCursor<Document> mongoCursor = findIterable.iterator();
         	while(mongoCursor.hasNext()){
                System.out.println(mongoCursor.next());
         	} 
      } catch (Exception e) {  
          System.err.println( e.getClass().getName() + ": " + e.getMessage() );  
      } 
	}  

	public int init() throws Throwable {
    connection("172.16.1.157",8096,"test10");
		return 0;
	}//end of init

	public int action() throws Throwable {
	    int radNum=(int)(Math.random()*100);//随机数,判断删除和更新
	    String getTimes="<getTime>";//插入数据的时间
	    lr.start_transaction("插入数据");
            List<Document> documentList = new ArrayList<Document>();  
            Document document1 = new Document("DataName", "MongoDB-<RadNum><RadNum2>").  
                    append("DataType", 1).  
                    append("remark", "From Loadrunner").
                    append("Date", new Document("InsertTime", getTimes).append("UpdateTime", null));
            documentList.add(document1);

            Document document2 = new Document();  
            document2.put("name", "<BJX><XM>");  
            document2.put("age", Integer.parseInt("<ages>"));  
            document2.put("address", "<DZ>");  
            documentList.add(document2); 
            //批量插入操作
            insertBatch(documentList,"test");
	    lr.end_transaction("插入数据", lr.AUTO);
         	/*以新插入数据id作为删除和更新的条件(因为id已建立了索引和分片,能保证操作速度)*/
         	ObjectId id_1 = (ObjectId)document1.get( "_id" );//第一条插入数据id
         	ObjectId id_2 = (ObjectId)document2.get( "_id" );//第二条插入数据id           

         	//System.out.println("随机数:"+radNum);
         	if(radNum<50){/*针对插入的两条数据,随机删除其中一条*/
					lr.start_transaction("删除操作");
		    			//String delKey="DataName";
		    			//String delKeyValue="MongoDB-<RadNum><RadNum2>";
		    			String delKey="_id";
		    			ObjectId delKeyValue=id_1;
		    			deleteByDbs(delKey,delKeyValue,"test");
					lr.end_transaction("删除操作", lr.AUTO);
         	}else{
					lr.start_transaction("删除操作");
		    			//String delKey="name";
		    			//String delKeyValue="<BJX><XM>";
		    			String delKey="_id";
		    			ObjectId delKeyValue=id_2;
		    			deleteByDbs(delKey,delKeyValue,"test");
					lr.end_transaction("删除操作", lr.AUTO);
         	}

	    lr.start_transaction("更新操作");
				String updKey=null;
				ObjectId updKeyValue=null;
				Document updatedValue=null;
				if(radNum>=50){
		    		//updKey="DataName";
		    		//updKeyValue="MongoDB-<RadNum><RadNum2>";
		    		updKey="_id";
		    		updKeyValue=id_1;   
		    		updatedValue=new Document();  
		    		updatedValue.put("DataType", 2);  
		    		updatedValue.put("Date", new Document("InsertTime", getTimes).append("UpdateTime", "<getTime>"));
				}else{
		    		//where name='小张'
		    		//updKey="name";
		    		//updKeyValue="<BJX><XM>";
		    		updKey="_id";
		    		updKeyValue=id_2;
          
		    		updatedValue=new Document();  
		    		updatedValue.put("age", Integer.parseInt("<ages>"));  
		    		updatedValue.put("address", "<DZ>-update");  
				}
				Document updateSetValue=new Document("$set",updatedValue);
				update(updKey, updKeyValue, updateSetValue, "test");
	    lr.end_transaction("更新操作", lr.AUTO);

	    lr.start_transaction("查询操作");
				Document ref=new Document();  
          
				//1、查询出年龄大于25岁并且小于65岁     
				ref.put("age", new Document("$gte",25));  
				ref.put("age", new Document("$lte",65));  
                  				find(ref,null,Integer.parseInt("<i>"),Integer.parseInt("<n>"),"test");//查询获取第i条开始的n条记录
		
	    lr.end_transaction("查询操作", lr.AUTO);

				//统计数据库记录数  
				/*mongoCollection = mongoDatabase.getCollection("test");
			long cnt1 = mongoCollection.count(Filters.eq("remark", "From Loadrunner"));//统计更新的记录数
			lr.log_message("统计数据1记录数:"+cnt1);
			long cnt2 = mongoCollection.count(Filters.eq("age", new Document("$gte",0)));//统计更新的记录数
			lr.log_message("统计数据2记录数:"+cnt2);*/

			return 0;
	}//end of action

	public int end() throws Throwable {
			mongoClient.close();
			mongoDatabase=null;
			mongoClient=null;
	    return 0;
	}//end of end
	
}


目录
相关文章
|
2天前
|
SQL 存储 关系型数据库
数据库开发之图形化工具以及表操作的详细解析
数据库开发之图形化工具以及表操作的详细解析
19 0
|
JavaScript 关系型数据库 MySQL
❤Nodejs 第六章(操作本地数据库前置知识优化)
【4月更文挑战第6天】本文介绍了Node.js操作本地数据库的前置配置和优化,包括处理接口跨域的CORS中间件,以及解析请求数据的body-parser、cookie-parser和multer。还讲解了与MySQL数据库交互的两种方式:`createPool`(适用于高并发,通过连接池管理连接)和`createConnection`(适用于低负载)。
17 0
|
15天前
|
测试技术 C语言
网站压力测试工具Siege图文详解
网站压力测试工具Siege图文详解
23 0
|
1月前
|
SQL 数据库连接 数据库
你不知道ADo.Net中操作数据库的步骤【超详细整理】
你不知道ADo.Net中操作数据库的步骤【超详细整理】
16 0
|
1月前
|
测试技术
现代软件测试中的自动化工具与挑战
传统软件测试面临着越来越复杂的系统架构和不断增长的测试需求,自动化测试工具应运而生。本文将探讨现代软件测试中自动化工具的应用和挑战,深入分析其优势与局限性,为软件测试领域的发展提供思路和启示。
|
1月前
|
jenkins 测试技术 持续交付
现代软件测试中的自动化工具与挑战
随着软件开发领域的不断发展,自动化测试工具在测试过程中扮演着越来越重要的角色。本文将探讨现代软件测试中自动化工具的应用及面临的挑战,旨在帮助开发人员和测试人员更好地理解和应对自动化测试中的问题。
|
1天前
|
NoSQL MongoDB 数据库
MongoDB数据恢复—MongoDB数据库文件被破坏的数据恢复案例
服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据库服务的情况下,将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分区进行了格式化操作,然后将数据库文件拷回原分区,重新启动MongoDB服务,服务无法启动。
|
5天前
|
NoSQL MongoDB Redis
Python与NoSQL数据库(MongoDB、Redis等)面试问答
【4月更文挑战第16天】本文探讨了Python与NoSQL数据库(如MongoDB、Redis)在面试中的常见问题,包括连接与操作数据库、错误处理、高级特性和缓存策略。重点介绍了使用`pymongo`和`redis`库进行CRUD操作、异常捕获以及数据一致性管理。通过理解这些问题、易错点及避免策略,并结合代码示例,开发者能在面试中展现其技术实力和实践经验。
99 8
Python与NoSQL数据库(MongoDB、Redis等)面试问答
|
15天前
|
测试技术 Linux Apache
网站压力测试工具webbench图文详解
网站压力测试工具webbench图文详解
12 0
|
15天前
|
存储 关系型数据库 MySQL
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)

热门文章

最新文章