性能测试Jmeter压测ZooKeeper-自定义java请求

   要想通过自定义java请求来压测ZooKeeper,那么我们就需要做两件事情,第一我们需要知道java如何操作ZooKeeper,第二就是怎么能将我们写的jar包让jmeter识别,首先我们先来干第一件事。

一、java操作ZooKeeper

以下的代码是网上百度找到的,经过了一点点修改(对于测试其它的可以找其它的测试代码)

package com.comtop.ZookApi;

import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

/**
 * Zookeeper base学习笔记
 */
public class ZookeeperBase {

    /** zookeeper地址 */
    static final String CONNECT_ADDR = "10.10.3.136:32372";
    /** session超时时间 */
    static final int SESSION_OUTTIME = 2000;// ms
    /** 信号量,阻塞程序执行,用于等待zookeeper连接成功,发送成功信号 */
    static final CountDownLatch connectedSemaphore = new CountDownLatch(1);

    public static void main(String[] args) throws Exception {

        ZooKeeper zk = new ZooKeeper(CONNECT_ADDR, SESSION_OUTTIME,
                new Watcher() {
                    public void process(WatchedEvent event) {
                        // 获取事件的状态
                        KeeperState keeperState = event.getState();
                        EventType eventType = event.getType();
                        // 如果是建立连接
                        if (KeeperState.SyncConnected == keeperState) {
                            if (EventType.None == eventType) {
                                // 如果建立连接成功,则发送信号量,让后续阻塞程序向下执行
                                System.out.println("zk 建立连接");
                                connectedSemaphore.countDown();
                            }
                        }
                    }
                });

        // 进行阻塞
        connectedSemaphore.await();

        System.out.println("..");
//         创建父节点
//         zk.create("/testRoot", "testRoot".getBytes(), Ids.OPEN_ACL_UNSAFE,
//         CreateMode.PERSISTENT);

//         创建子节点
//         zk.create("/testRoot/children", "children data".getBytes(),
//         Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        // 获取节点洗信息
//         byte[] data = zk.getData("/testRoot/children", false, null);
//         System.out.println(new String(data));
//         System.out.println(zk.getChildren("/testRoot", false));
        // 修改节点的值
//         zk.setData("/testRoot/children", "modify data root".getBytes(), -1);
//         byte[] data = zk.getData("/testRoot/children", false, null);
//         System.out.println(new String(data));
// 如果存在节点则删除节点
         if (null != zk.exists("/testRoot/children", false)) {
             // 删除节点
             zk.delete("/testRoot/children", -1);
             System.out.println(zk.exists("/testRoot/children", false));
         }
        zk.close();

    }

}

 

二、自定义java请求

一、环境准备
        1、新建一个java工程
        2、导入jar包:ApacheJMeter_core.jar     ApacheJMeter_java.jar    (该包在本地C:\apache-jmeter-3.0\lib\ext下,当然路径取决于本地环境)
                这两个jar是使用jmeter最基础的jar,能够让你的代码在jmeter中运行起来,如果在写代码的过程中需要其他的jar,自行导入。
 
二、写代码前该知道的
        1、如果想要让你的代码在jmeter中运行起来,在创建类的时候需要去继承AbstractJavaSamplerClient抽象类或者是实现JavaSamplerClient接口
            AbstractJavaSamplerClient抽象类是JavaSamplerClient接口的子类,当你不需要复写所有的需要复写的方法时,那么你只需要去继承AbstractJavaSamplerClient抽象类即可。
 
            如果你选择了实现JavaSamplerClient接口,那么你需要复写的方法有:
                         public SampleResult runTest(JavaSamplerContext context) {}
                         public void setupTest(JavaSamplerContext context) {}
                         public void teardownTest(JavaSamplerContext context) {}
                         public Arguments getDefaultParameters() {}
            这4个方法就必须要复写,但是如果选择继承AbstractJavaSamplerClient这个抽象类,那么只需要复写你需要的方法即可。
 
        2、方法说明:
                    public Arguments getDefaultParameters() {}
                            这个方法由Jmeter在进行添加javaRequest时第一个运行,它决定了你要在GUI中默认显示出哪些属性。
                    public void setupTest(JavaSamplerContext context) {}
                            这个方法相当于loadrunner中的init,我们可以用它来进行一些初始化的动作。
                    public SampleResult runTest(JavaSamplerContext context) {}
                            这个方法相当于loadrunner中的action,我们的核心测试代码就在这里了。
                    public void teardownTest(JavaSamplerContext context) {}
                            这个方法相当于loadrunner中的end,收尾的工作可以由它来做。
 
        3、除了以上2点,我们一般还需要去实现Serializable,序列化标记接口,这样可以让我们的类去实现序列化。
 
整体代码如下:
package com.comtop.ZkApiJM;
 
 
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
 
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.util.concurrent.CountDownLatch;

import javax.management.RuntimeErrorException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper.States;
import org.apache.zookeeper.ZooKeeper;

//public Arguments getDefaultParameters();设置可用参数及的默认值;
//public void setupTest(JavaSamplerContext arg0):每个线程测试前执行一次,做一些初始化工作;
//public SampleResult runTest(JavaSamplerContext arg0):开始测试,从arg0参数可以获得参数值;
//public void teardownTest(JavaSamplerContext arg0):测试结束时调用;

public class ZkjavaRequest extends AbstractJavaSamplerClient implements Serializable  {
 
    /** zookeeper地址 */
    private String conn_addr;    //存储用户输入的zk地址
//    测试用的数据
//    private static String conn_addr1;
//    private static String session_timeout1;
//    private static String zk_father1;
//    private static String zk_children1;
//    private static String zk_context1;
//    private static String resultData1;
    
    private static final String ConnAddrName="conn_addr" ;    //设置GUI页面显示的变量名称
    //设置GUI页面默认显示的变量值,默认值为空
    private static final String ConnAddrValueDefault="10.10.3.136:32372";
    
    /** session超时时间 */
    private String session_timeout;    //存储用户输入的session超时时间(单位ms)
    
    private static final String SessTimeName="session_timeout" ;    //设置GUI页面显示的变量名称
    //设置GUI页面默认显示的变量值,默认值为空
    private static final String SessTimeValueDefault="5000";

    //zk父节点
    private  String zk_father = "test";    //存储用户输入的zk父节点
    private static final String ZkFatherName="zk_father" ;    //设置GUI页面显示的变量名称
    //设置GUI页面默认显示的变量值,默认值为空
    private static final String ZkFatherValueDefault="/test";
    
    /** 信号量,阻塞程序执行,用于等待zookeeper连接成功,发送成功信号 */
    static final CountDownLatch connectedSemaphore = new CountDownLatch(1);
    
    //zk连接对象
    private ZooKeeper zk;
    
    // resultData变量用来存储响应的数据,目的是显示到查看结果树中。
    private String resultData;

    // 测试代码
//    public static void main(String[] args) {
//        haha();
//    }
//
//    public static void haha(){
//        conn_addr1 = "10.10.3.136:32372";
//        session_timeout1 = "2000";
//        zk_father1 = "/test1";
//        zk_children1 = "/test2";
//        zk_context1 = "test2";
//        try {
//            ZooKeeper zk = new ZooKeeper(conn_addr1, Integer.valueOf(session_timeout1),
//                    new Watcher() {
//                        public void process(WatchedEvent event) {
//                            // 获取事件的状态
//                            KeeperState keeperState = event.getState();
//                            EventType eventType = event.getType();
//                            // 如果是建立连接
//                            if (KeeperState.SyncConnected == keeperState) {
//                                if (EventType.None == eventType) {
//                                    // 如果建立连接成功,则发送信号量,让后续阻塞程序向下执行
//                                    System.out.println("zk 建立连接");
//                                    connectedSemaphore.countDown();
//                                }
//                            }
//                        }
//                    });
//            connectedSemaphore.await();
//            // 如果存在父节点则不创建父节点
//             if (null == zk.exists(zk_father1, false)) {
//                 //               创建父节点
//               zk.create(zk_father1, zk_father1.getBytes(), Ids.OPEN_ACL_UNSAFE,
//               CreateMode.PERSISTENT);
//             }
//          // 创建子节点
//              zk.create(zk_father1+zk_children1, zk_context1.getBytes(),
//              Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//              // 获取节点洗信息
//            byte[] data = zk.getData(zk_father1+zk_children1, false, null);
//            resultData1 = new String(data);
//            System.out.println(new String(data));
//            System.out.println(zk.getChildren("/testRoot", false));
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
//}
  
    /*
     * 这个方法用来控制显示在GUI页面的属性,由用户来进行设置。
     * 此方法不用调用,是一个与生命周期相关的方法,类加载则运行。
     * (non-Javadoc)
     * @see org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient#getDefaultParameters()
     */
    
    @Override
    public Arguments getDefaultParameters() {
        System.out.println("读取属性值");
        Arguments params = new Arguments();
        params.addArgument("conn_addr",String.valueOf(ConnAddrValueDefault));
        params.addArgument("session_timeout", String.valueOf(SessTimeValueDefault));
        params.addArgument("zk_father", String.valueOf(ZkFatherValueDefault));
        params.addArgument("zk_children","");
        params.addArgument("zk_context","");
        return params;
    }
 
    /**
     * 初始化方法,初始化性能测试时的每个线程
     * 实际运行时每个线程仅执行一次,在测试方法运行前执行,类似于LoadRunner中的init方法
     */
 
    @Override
    public void setupTest(JavaSamplerContext jsc) {
        conn_addr = jsc.getParameter(ConnAddrName, ConnAddrValueDefault);
        session_timeout = jsc.getParameter(SessTimeName, SessTimeValueDefault);
        zk_father = jsc.getParameter(ZkFatherName, ZkFatherValueDefault);
        try {
            zk = new ZooKeeper(conn_addr, Integer.valueOf(session_timeout),
                    new Watcher() {
                        public void process(WatchedEvent event) {
                            // 获取事件的状态
                            KeeperState keeperState = event.getState();
                            EventType eventType = event.getType();
                            // 如果是建立连接
                            if (KeeperState.SyncConnected == keeperState) {
                                if (EventType.None == eventType) {
                                    // 如果建立连接成功,则发送信号量,让后续阻塞程序向下执行
                                    System.out.println("zk 建立连接");
                                    connectedSemaphore.countDown();
                                }
                            }
                        }
                    });
            if (States.CONNECTING == zk.getState()) { 
                connectedSemaphore.await();
            }
            // 如果存在父节点则不创建父节点
             if (null == zk.exists(zk_father, false)) {
                 //               创建父节点
               zk.create(zk_father, zk_father.getBytes(), Ids.OPEN_ACL_UNSAFE,
               CreateMode.PERSISTENT);
             }
        } catch (Exception e) {
            // TODO Auto-generated catch block
//            e.printStackTrace();
            throw new RuntimeException(e);
        }
        // 进行阻塞
//        System.out.println("..");
         
    }
 
    @Override
    public SampleResult runTest(JavaSamplerContext arg0) {
        String zk_children = arg0.getParameter("zk_children");    //获取zk_children
        String zk_context = arg0.getParameter("zk_context");    //获取zk_context
//        System.out.println(zk_context+" "+zk_children);
        /*
         * SampleResult这个类是用来将测试结果输出到查看结果树中的。  
         * 并且也是用来控制事务的开始和结束的。  
         */
    
        SampleResult results = new SampleResult();
        results.setSampleLabel("zk节点测试:"+zk_father);
 
        try{ 
            // 事务开始标记           
            results.sampleStart();
            // 创建子节点
            zk.create(zk_father+zk_children, zk_context.getBytes(),
                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            // 获取节点洗信息
            byte[] data = zk.getData(zk_father+zk_children, false, null);
//            System.out.println(new String(data));
            resultData = new String(data);
            if(null == resultData){
                results.setSuccessful(false);
                results.setResponseData("zk result is null",null);
                results.setDataType(SampleResult.TEXT);
            }
            results.setSuccessful(true);
        }catch(Exception e){
            results.setSuccessful(false);
            results.setResponseData(e.toString(),null);
            results.setDataType(SampleResult.TEXT);
            e.printStackTrace();
            return results;
        }finally{
            //标记事务结束
            results.sampleEnd();
        }
//        System.out.println("写入成功");
//        results.setSuccessful(true);
        results.setResponseData(resultData,null);//将数据打印到查看结果树当中
        results.setDataType(SampleResult.TEXT);
        return results;
    }

    /**
     * 测试结束方法,结束测试中的每个线程
     * 实际运行时,每个线程仅执行一次,在测试方法运行结束后执行,类似于Loadrunner中的End方法
     */
    
    public void teardownTest(JavaSamplerContext arg0) {
        try {
            zk.close();
            System.out.println("关闭");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 
}
    

代码及依赖包如下:

 

转载于:https://www.cnblogs.com/leixiaobai/p/10245991.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Version: Applicable to JMeter 2.8+(适用JMeter版本) 以下为官方说明: Prepare a simple IdGenerator For security reasons, ZK generates ID randomly. However to perform a record & reply test, it is mandatory to fix the IDs of the components. The IdGenerator here is used to create a predictable component id when testing. ———— 官方描述地址 http://blog.zkoss.org/index.php/2013/08/06/zk-jmeter-plugin/ 编译后的class文件,是需要配合jar包一起用的,用来自动关联uuid和data,jar包里面只解决了dtid。因为官方提供源码,需要自己编译后才可以用,我这里是已经编译好的class。(提供给那些没有条件编译的朋友) ———— 使用方法: 1.解压后classes\foo\jmtest目录 直接覆盖在 被测的ZK平台对应目录中(WEB-INF下)。 2.修改zk.xml文件,添加下面内容(WEB-INF下) foo.jmtest.SimpleIdGenerator 3.安装ZK的JMeter插件 把压缩包中的 zk-jmeter-plugin-0.8.0.jar 文件,复制到 JMETER_HOME\lib\ext. ———— 安装完整,重新打开JMeter,可以添加ZK http 代理,录制脚本试试。 下面录制步骤: Prepare a Test Plan 1.Create a Thread Group in Test Group. 2.Add HTTP Cookie Manager in Thread Group 3.Add HTTP Request Defaults in Thread Group. 4.Add Transaction Controller in Thread Group. 5.Edit HTTP Request Defaults, set the Server Name and Port Number. 6.Create a ZK HTTP Proxy Server (Add > Non-Test Elements) in WorkBench, and edit it as follows Set Target Controller to Test Plan > Thread Group > Transaction Controller 7.Start the ZK HTTP Proxy Server

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值