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

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
性能测试 PTS,5000VUM额度
简介: 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
	
}


目录
相关文章
|
5天前
|
存储 JSON NoSQL
学习 MongoDB:打开强大的数据库技术大门
MongoDB 是一个基于分布式文件存储的文档数据库,由 C++ 编写,旨在为 Web 应用提供可扩展的高性能数据存储解决方案。它与 MySQL 类似,但使用文档结构而非表结构。核心概念包括:数据库(Database)、集合(Collection)、文档(Document)和字段(Field)。MongoDB 使用 BSON 格式存储数据,支持多种数据类型,如字符串、整数、数组等,并通过二进制编码实现高效存储和传输。BSON 文档结构类似 JSON,但更紧凑,适合网络传输。
31 15
|
13天前
|
存储 NoSQL 关系型数据库
阿里云数据库MongoDB版助力信也科技 打造互联网金融企业样板
我们的风控系统引入阿里云数据库MongoDB版后,解决了特征类字段灵活加减的问题,大大提高了开发效率,极大的提升了业务用户体验,获得了非常好的效果
阿里云数据库MongoDB版助力信也科技 打造互联网金融企业样板
|
1月前
|
SQL 关系型数据库 数据库
国产数据实战之docker部署MyWebSQL数据库管理工具
【10月更文挑战第23天】国产数据实战之docker部署MyWebSQL数据库管理工具
142 4
国产数据实战之docker部署MyWebSQL数据库管理工具
|
1月前
|
NoSQL Cloud Native atlas
探索云原生数据库:MongoDB Atlas 的实践与思考
【10月更文挑战第21天】本文探讨了MongoDB Atlas的核心特性、实践应用及对云原生数据库未来的思考。MongoDB Atlas作为MongoDB的云原生版本,提供全球分布式、完全托管、弹性伸缩和安全合规等优势,支持快速部署、数据全球化、自动化运维和灵活定价。文章还讨论了云原生数据库的未来趋势,如架构灵活性、智能化运维和混合云支持,并分享了实施MongoDB Atlas的最佳实践。
|
2月前
|
NoSQL Cloud Native atlas
探索云原生数据库:MongoDB Atlas 的实践与思考
【10月更文挑战第20天】本文探讨了MongoDB Atlas的核心特性、实践应用及对未来云原生数据库的思考。MongoDB Atlas作为云原生数据库服务,具备全球分布、完全托管、弹性伸缩和安全合规等优势,支持快速部署、数据全球化、自动化运维和灵活定价。文章还讨论了实施MongoDB Atlas的最佳实践和职业心得,展望了云原生数据库的发展趋势。
|
2月前
|
存储 NoSQL MongoDB
MongoDB 数据库引用
10月更文挑战第20天
24 1
|
存储 测试技术
Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
140 0
Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
|
Java 测试技术 Android开发
Loadrunner脚本开发-基于HTTP协议的流媒体视频在线播放服务器性能测试
Loadrunner脚本开发-基于HTTP协议的流媒体视频在线播放服务器性能测试
162 0
|
XML 存储 测试技术
Loadrunner 脚本开发-soap_request函数介绍及WebService接口测试
Loadrunner 脚本开发-soap_request函数介绍及WebService接口测试
160 0
|
JSON 测试技术 数据格式
Loadrunner 脚本开发-利用web_custom_request函数进行接口测试
Loadrunner 脚本开发-利用web_custom_request函数进行接口测试
109 0