Loadrunner11模拟多客户端并发对服务器并发处理socket请求的能力进行性能测试,C语言编写的winsocket Vuser脚本比较常见和简单,Java由于第三方库的庞大,能做的事情很多,这里介绍一下用Java写的脚本模拟socket客户端的压力测试情况。
主要环境:
1,JDK1.6
2,LoadRunner11
3,ApacheMINA2.09
基本流程是:
1,以MINA写成的java 同步客户端,打包为jar文件,需要参数,在LR11中为File形式提供参数;
2,在LR11的Vuser Generator中选择建立Java Vuser
3,在Vuser Generator的Run-time Setting > Java Enviroment settings > Classpath 中选择 Add Jar or zip file,把打包的java mina同步客户端jar文件和必要的库文件引入。
4,Vuser Generator的 Parameters List设定页,新建一个File类型的参数列表PARAMS,引入实现编辑好的参数列文件。
5,在Vuser Generator的View Script,在Actions中加入Java socket客户端调用。
6,建立测试场景。
7,在LR11的Controller中引入测试场景,设定并发测试参数。
8,在LR11的Controller中启动场景对服务器进行并发测试。
9,在LR11和服务端日志中分析测试结果 。
部分代码:
MINA同步客户端
package lr.test1; import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.future.ReadFuture; import org.apache.mina.core.future.WriteFuture; import org.apache.mina.core.service.IoConnector; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class CommandSender { private static Logger logger = Logger.getLogger(CommandSender.class.getName()); private String port ; private String ip ; private String cmdtype; private int poolSize = 1; private LinkedBlockingQueue<IoSession> pool; private IoConnector connector = null; private static int CMDTIMEOUT_MILL = 2000;//等待回应的超时时间(毫秒) public CommandSender(String ip,String port, String cmdtype) { this.ip = ip; this.port = port; this.cmdtype = cmdtype; } public String sendpacket(String cmd){ if( !initclient() ){ logger.error("Connect failed!"); return null; } String res = sendmsg(cmd); this.close(); return res; } public boolean initclient() { boolean res = true; try { connector = new NioSocketConnector(); connector.getSessionConfig().setUseReadOperation(true); DefaultIoFilterChainBuilder chain = connector.getFilterChain(); ProtocolCodecFilter cd = new ProtocolCodecFilter(new minaCodeFactory(Charset.forName("UTF-8"))); chain.addLast("chainin", cd); connector.getSessionConfig().setReadBufferSize(1024); connector.getSessionConfig().setMaxReadBufferSize(2048); pool = new LinkedBlockingQueue<IoSession>(poolSize); for (int i = 0; i < poolSize; i++) { ConnectFuture connectF = connector.connect(new InetSocketAddress(ip, Integer.valueOf(port))); connectF.awaitUninterruptibly(); IoSession session = connectF.getSession(); pool.put(session); } } catch (Exception e) { logger.error("Connected to server failed, "+e.toString()); res = false; } return res; } private String sendmsg(String msg){ IoSession session = null; String res = ""; try { session = pool.take(); if (session == null) { logger.error("CommandSender sendmsg session null. ["+msg+"]"); return res; }; WriteFuture writeF = session.write(msg).awaitUninterruptibly(); if (writeF.getException() != null) { logger.error("CommandSender sendmsg,"+writeF.getException().getMessage()+",["+msg +"]"); }else if (writeF.isWritten() ){ ReadFuture readF = session.read(); if( readF.awaitUninterruptibly(CMDTIMEOUT_MILL,TimeUnit.MILLISECONDS) ){ res = readF.getMessage().toString().trim(); logger.info("CommandSender sendmsg complete, response: "+ res + ",[" + msg + "]"); }else{ logger.error("CommandSender sendmsg,response timeout! ["+ msg +"]"); } }else{ logger.error("CommandSender sendmsg error, "+msg); } } catch (Exception e) { logger.error("CommandSender sendmsg error, "+e.toString()); }finally { try { pool.put(session); } catch (Exception e) { logger.error("CommandSender sendmsg error, "+e.toString()); } } return res; } public void close() { this.connector.dispose(); } } package lr.test1; public class LRJava1 { /** * @param args */ public static void main(String[] args) { String ip = args[0]; String port = args[1]; String param = args[2]; String cmdtype = args[3]; CommandSender c = new CommandSender(ip,port,cmdtype); c.sendpacket("^HEADER^"+ param +"^^content"); } }
Vuser Script Actions部分代码:
/* * LoadRunner Java script. (Build: _build_number_) * * Script Description: * */ import lrapi.*; import lr.test1.LRJava1; public class Actions { public int init() throws Throwable { return 0; }//end of init public int action() throws Throwable { //设置集合点 lr.rendezvous("集合点"); lr.start_transaction("j1"); LRJava1.main(new String[]{"192.168.1.2","9999", "<PARAMS>", "REQUEST1"}); lr.end_transaction("j1", lr.AUTO); return 0; } public int end() throws Throwable { return 0; }//end of end }