zoukankan      html  css  js  c++  java
  • 性能测试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.0libext下,当然路径取决于本地环境)
                    这两个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();
            }
        }
     
    }
        

    代码及依赖包如下:

  • 相关阅读:
    Hive的安装搭建(二)
    Hive的基本介绍(一)
    HADOOP之HDFS使用idea练习MapReduce(八)
    HADOOP之HDFS使用idea操作MapReduce(七)
    HADOOP之HDFS增加MapReduce(六)
    HADOOP之HDFS用idea操作(五)
    HADOOP之HDFS环境搭建(四)
    HADOOP之HDFS环境搭建(三)
    HADOOP之HDFS环境搭建(二)
    HADOOP之HDFS环境搭建(一)
  • 原文地址:https://www.cnblogs.com/leixiaobai/p/10245991.html
Copyright © 2011-2022 走看看