`
冲杯茶喝
  • 浏览: 30576 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Jmeter“Java请求”使用总结

阅读更多

1. 线程组,在我们测试方案里面,每个线程模拟一个用户,执行用户的登录、等等等一系列的操作。由于我们的项目是长连接的,如何能实现多个sample公用一个长连接客户端,考虑了很久,最后实现方法如下:
 1 package tea.client.network;
 2 /**
 3  * @author Teaey
 4  * @creation 2012-8-25
 5  */
 6 public class NetworkClientHolder
 7 {
 8     /**
 9      * 这里使用ThradLocal存储BaseClient
10      * 方便一轮测试的每个sample都是由同一个socketChannel发送
11      * 更真实的模拟用户
12      */
13     private static ThreadLocal<BaseClient> clientHolder = new ThreadLocal<BaseClient>();
14     public static BaseClient getClient(String ip, String port)
15     {
16         BaseClient client = clientHolder.get();
17         if (null == client)
18         {
19             client = new BaseClient(ip, port);
20             client.connect();
21             clientHolder.set(client);
22         }
23         return client;
24     }
25 }
26 
代码中使用thread_local保存Socket客户端,这样每个sample中发送数据的客户端都是从这里拿的,就可以保证长连接的情况下,socket不会重复创建,很好的模拟了用户。
当然不单单是链接可以保存,所有需要在线程中共享的数据都可以通过这种方法来实现。
2. 接下来是如何封装发送请求的客户端,这里用的netty,具体可以根据项目情况使用mina或者nio都可以。代码直接明了^_^:
  1 package tea.client.network;
  2 
  3 import java.net.InetSocketAddress;
  4 import java.util.concurrent.Executors;
  5 import org.jboss.netty.bootstrap.ClientBootstrap;
  6 import org.jboss.netty.channel.Channel;
  7 import org.jboss.netty.channel.ChannelFuture;
  8 import org.jboss.netty.channel.ChannelHandlerContext;
  9 import org.jboss.netty.channel.ChannelPipeline;
 10 import org.jboss.netty.channel.ChannelPipelineFactory;
 11 import org.jboss.netty.channel.ChannelStateEvent;
 12 import org.jboss.netty.channel.Channels;
 13 import org.jboss.netty.channel.ExceptionEvent;
 14 import org.jboss.netty.channel.MessageEvent;
 15 import org.jboss.netty.channel.SimpleChannelHandler;
 16 import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
 17 import tea.common.network.ClientDecoder;
 18 import tea.common.network.ClientEncoder;
 19 import tea.common.network.ClientMessage;
 20 
 21 /**
 22  * @author Teaey
 23  * @creation 2012-8-25
 24  */
 25 public class BaseClient
 26 {
 27     public BaseClient(String ip, String port)
 28     {
 29         this.ip = ip;
 30         this.port = port;
 31     }
 32     private String           ip;
 33     private String           port;
 34     private Channel          channel;
 35     private ClientBootstrap  bootstrap;
 36     private Object           syn             = new Object();
 37     private static final int Receive_Timeout = 10000;       //ms
 38     private ClientMessage    response        = null;
 39     public void connect()
 40     {
 41         bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
 42         bootstrap.setOption("tcpNoDelay", true);
 43         bootstrap.setPipelineFactory(new ClientPipelineFactory());
 44         while (true)
 45         {
 46             ChannelFuture future = bootstrap.connect(new InetSocketAddress(ip, Integer.parseInt(port)));
 47             future.awaitUninterruptibly(5000);
 48             if (future.isDone())
 49             {
 50                 channel = future.getChannel();
 51                 if (channel != null && channel.isConnected())
 52                 {
 53                     break;
 54                 }
 55             }
 56         }
 57     }
 58     public void disconnect()
 59     {
 60         if (channel.isConnected())
 61         {
 62             channel.disconnect();
 63         }
 64     }
 65     public boolean isConnected()
 66     {
 67         return channel.isConnected();
 68     }
 69     public void close()
 70     {
 71         if (this.channel.isOpen())
 72         {
 73             this.channel.close();
 74         }
 75         bootstrap.releaseExternalResources();
 76     }
 77     /**
 78      * 发送消息,无需返回
 79      */
 80     public void send(ClientMessage message)
 81     {
 82         channel.write(message);
 83     }
 84     /**
 85      * 发送消息,等待返回
 86      */
 87     public ClientMessage sendWaitBack(ClientMessage message)
 88     {
 89         response = null;
 90         try
 91         {
 92             channel.write(message);
 93             synchronized (syn)
 94             {
 95                 try
 96                 {
 97                     syn.wait(Receive_Timeout);
 98                 } catch (InterruptedException e)
 99                 {
100                     e.printStackTrace();
101                 }
102             }
103             if (null == response)
104             {
105                 System.err.println("Receive response timeout");
106             }
107         } catch (Exception e)
108         {
109             e.printStackTrace();
110         }
111         return response;
112     }
113     class ClientPipelineFactory implements ChannelPipelineFactory
114     {
115         public ChannelPipeline getPipeline() throws Exception
116         {
117             ChannelPipeline p = Channels.pipeline();
118             p.addLast("frameDecoder", new ClientDecoder());
119             p.addLast("fremeEncoder", new ClientEncoder());
120             p.addLast("logicHandler", new ClientMsgHandler());
121             return p;
122         }
123     }
124     class ClientMsgHandler extends SimpleChannelHandler
125     {
126         public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
127         {
128             Object obj = e.getMessage();
129             if (obj instanceof ClientMessage)
130             {
131                 ClientMessage msg = (ClientMessage) obj;
132                 response = msg;
133                 synchronized (syn)
134                 {
135                     syn.notifyAll();
136                 }
137             }
138         }
139         public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
140         {
141             System.out.println("connected server:" + ctx.getChannel());
142         }
143         public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
144         {
145             System.out.println("disconnected server:" + ctx.getChannel());
146         }
147         public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception
148         {
149             System.out.println("Error in exceptionCaught:" + e.getCause());
150         }
151     }
152 }
153 
这段代码展示了我们的客户端,这里所有的请求有两种发送模式,一种是发送并阻塞等待返回(sendWaitBack
),第二种就是直接发送(send)。
3. 有了发送请求的客户端,那如何能够更简单的实现一个协议好让客户端发送,再贴一段代码^_^:
  1 package tea.client.network;
  2 
  3 import org.apache.jmeter.config.Arguments;
  4 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
  5 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
  6 import org.apache.jmeter.samplers.SampleResult;
  7 import com.google.protobuf.InvalidProtocolBufferException;
  8 import com.google.protobuf.MessageLite;
  9 
 10 /**
 11  * @author Teaey
 12  * @creation 2012-8-25
 13  */
 14 public abstract class BaseSample extends AbstractJavaSamplerClient
 15 {
 16     public static final String PARAM_IP   = "ip";
 17     public static final String PARAM_PORT = "port";
 18     public static final String VAR_IP     = "${ip}";
 19     public static final String VAR_PORT   = "${port}";
 20     protected BaseClient       client;
 21     public void addParameter(Arguments params)
 22     {
 23     }
 24     /**
 25      * Jmeter获取消息参数,默认配置ip和port两个参数
 26      * 如果子类有更多参数,调用super.getDefaultParameters()获取Arguments后,继续设置其他方法
 27      */
 28     @Override
 29     public Arguments getDefaultParameters()
 30     {
 31         System.out.println("1.getDefaultParameters");
 32         Arguments params = new Arguments();
 33         params.addArgument(PARAM_IP, VAR_IP);
 34         params.addArgument(PARAM_PORT, VAR_PORT);
 35         addParameter(params);
 36         return params;
 37     }
 38     /**
 39      * runTest的前置方法
 40      */
 41     @Override
 42     public void setupTest(JavaSamplerContext context)
 43     {
 44         System.out.println("2.setupTest:" + context.containsParameter(PARAM_IP));
 45         String ip = context.getParameter(PARAM_IP);
 46         String port = context.getParameter(PARAM_PORT);
 47         this.client = NetworkClientHolder.getClient(ip, port);
 48         System.out.println("thread--->" + Thread.currentThread().getId() + " client--->" + client);
 49     }
 50     /**
 51      * Jmeter调用,用于实际的测试
 52      */
 53     @Override
 54     public SampleResult runTest(JavaSamplerContext context)
 55     {
 56         SampleResult sample = getSample();
 57         sample.sampleStart();
 58         try
 59         {
 60             MessageLite response = doTest();
 61             String msg = response == null ? "" : response.toString();
 62             sample.setResponseMessage(msg);
 63             sample.setSuccessful(true);
 64         } catch (Exception e)
 65         {
 66             sample.setSuccessful(false);
 67             e.printStackTrace();
 68         } finally
 69         {
 70             sample.sampleEnd();
 71         }
 72         return sample;
 73     }
 74     /**
 75      * 获取本Sample的标签,子类实现
 76      */
 77     public abstract String getLabel();
 78     /**
 79      * 获取一个带标签的Sample 
 80      */
 81     public SampleResult getSample()
 82     {
 83         SampleResult sample = new SampleResult();
 84         sample.setSampleLabel(getLabel());
 85         return sample;
 86     }
 87     /**
 88      * Jmeter调用,用于
 89      */
 90     @Override
 91     public void teardownTest(JavaSamplerContext context)
 92     {
 93         System.out.println("4.teardownTest");
 94     }
 95     /**
 96      * 需实现,具体测试的方法,调用client的send/sendWithBack发送请求
 97      * 如无返回,放回null即可 
 98      */
 99     public abstract MessageLite doTest() throws InvalidProtocolBufferException;
100 }
好的,这里封装了下AbstractJavaSamplerClient,每个消息默认包含ip和port参数,这可以再jmeter的用户变量中定义好。为了方便大家添加消息的参数,这里实现了空的
addParameter(Arguments params)方法,这样在具体消息中直接重写这个方法,来添加具体的参数。是不是很方便?^_^,具体协议还需要实现的两个方法分别是:getLabel和doTest。第一个方法时用于报告显示的请求名字,一般定义为消息名字+“Label”就OKay。第二个方法就是我们重点重写的方法,这里再贴段代码,是一个具体消息的实现:
 1 package tea.client;
 2 
 3 import com.google.protobuf.InvalidProtocolBufferException;
 4 import com.google.protobuf.MessageLite;
 5 import tea.client.network.BaseSample;
 6 import tea.common.network.ClientMessage;
 7 import tea.common.network.RPC.HeartBeat_C2S;
 8 import tea.common.network.RPC.HeartBeat_S2C;
 9 
10 /**
11  * @author Teaey
12  * @creation 2012-8-24
13  */
14 public class HeartBeatSample extends BaseSample
15 {
16     @Override
17     public MessageLite doTest() throws InvalidProtocolBufferException
18     {
19         HeartBeat_C2S.Builder request = HeartBeat_C2S.newBuilder();
20         request.setTimestamp(System.currentTimeMillis());
21         ClientMessage cm = new ClientMessage();
22         cm.setContent(request.build().toByteArray());
23         cm.setName("HeartBeat");
24         ClientMessage sm = client.sendWaitBack(cm);
25         HeartBeat_S2C response = HeartBeat_S2C.parseFrom(sm.getContent());
26         return response;
27     }
28     @Override
29     public String getLabel()
30     {
31         return "HeartBeatSample";
32     }
33 }
34 
可以看到doTest的工作就是封装请求,并拿到父类的client发送,然后返回响应(send方式返回null),Okay,大功告成。
写得不好但属原创,体量作者转载请标明出处。感谢。
0
0
分享到:
评论

相关推荐

    使用Jmeter测试java请求

    总的来说,使用JMeter测试Java请求是性能测试中常见且重要的任务,它能帮助开发者识别和优化Java服务的性能问题,确保在高负载下仍能提供稳定的服务。在实际操作中,可能还需要结合其他工具和方法,如日志分析、监控...

    jmeter压测socket请求(java请求)

    jar包直接放进 jmeter安装目录的lib/ext 下即可使用,添加java请求,老铁赶紧下!!!!

    JMeter进行性能测试实例Java请求+参数化

    JMeter进行性能测试实例Java请求+参数化

    Jmeter Java Request Demo

    在本"Jmeter Java Request Demo"项目中,我们将会深入探讨如何利用JMeter进行Java请求,包括TCP、HTTP以及RocketMQ这三种不同类型的网络通信。 首先,让我们了解一下Java Request在JMeter中的应用。Java Request是...

    jmeter5.0 解决请求参数中文乱码ApacheJMeter_http.jar

    在这个场景下,我们关注的是如何解决在使用JMeter 5.0版本时遇到的请求参数中文乱码问题。 首先,中文乱码问题通常是由于字符编码不一致导致的。在HTTP请求中,如果服务器和客户端对字符编码的理解不同,就可能导致...

    jmeter java使用jar包

    jmeter java使用jar包,用于java请求书写ApacheJMeter_core.jar

    Jmeter-Java-Sampler.rar_jmeter_jmeter java_压力测试

    总结来说,JMeter Java Sampler为高级用户提供了一种强大的自定义测试手段,能够处理复杂的测试场景,实现对各种服务的压力和负载测试。通过熟练掌握Java Sampler的使用,我们可以更全面、准确地评估系统的性能表现...

    jmeter 各种请求接口使用方法

    jmeter 各种请求接口使用方法 jmeter 是 Apache 组织开发的基于 Java 的压力测试工具,用于对软件做压力测试。它最初被设计用于 Web 应用测试,但后来扩展到其他测试领域。jmeter 可以用于测试静态和动态资源,例如...

    JMeter 实现Java请求步骤及原理详解

    以下是对JMeter 实现Java请求步骤及原理详解的知识点总结: JMeter 的Java请求实现步骤 1. 添加jar包依赖:在JMeter的lib\ext目录下添加ApacheJMeter_core.jar和ApacheJMeter_java.jar这两个jar包,注意版本要与...

    JMeter beanShell修改http请求参数

    首先,BeanShell是JMeter内置的一个脚本引擎,允许用户使用类似Java语法的脚本来处理测试逻辑。在我们的例子中,主要涉及以下三个关键步骤: 1. **引入加密函数**: 在JMeter测试计划中,自定义加密函数通常需要...

    Jmeter Java Sampler编写入门.docx

    在JMeter中,创建一个新的Java请求Sampler,输入调用方法的代码,并指定目标方法(如`targetFunction`)和参数。 5. 执行测试: 运行JMeter测试计划,Java Sampler会执行指定的Java代码,测量响应时间和结果校验...

    jmeter测试dubbo请求

    而当我们谈论"jmeter测试dubbo请求"时,这意味着我们要利用JMeter对基于Dubbo框架的服务进行压力和负载测试。 Dubbo是阿里巴巴提供的一款高性能、轻量级的Java RPC框架,它使得服务调用变得简单,能有效提升分布式...

    基于jmeter+Java+HttpclientUtil实现的接口测试工具

    基于jmeter+Java+HttpclientUtil实现的接口测试工具,通过Excel表格进行维护接口相关参数信息,借助Jmeter工具通过java请求设计接口测试自动化测试用例。代码重写了JavaSampleClient类,在使用过程中取出了冗余的...

    jmeter压测经历--总结.pdf

    【JMeter压测经历与总结】 在进行JMeter压力测试时,我们首先需要确保API在Windows环境下能够正常工作。这包括调通所有的压测接口,确保接口能够无误地响应请求。在这个过程中,一个常见的问题就是内存管理,尤其是...

    Jmeter需要的Java环境.zip

    《JMeter运行所需的Java...总结,JMeter的正常运行离不开Java环境的支持,理解并配置好Java环境对于提升JMeter的测试效率至关重要。确保正确安装并优化Java环境,能够帮助我们充分利用JMeter进行高效、准确的性能测试。

    jmeter的详细使用教程

    JMeter是由Apache Software Foundation开发的一款Java应用程序,主要用于测试Web应用的性能和负载。它能够模拟多个用户并发执行各种测试操作,如HTTP请求、FTP请求、数据库连接等,进而评估系统的稳定性、响应时间和...

Global site tag (gtag.js) - Google Analytics