简介

JMeter作为Apache的开源性能测试工具允许使用者对其进行二次开发扩展,比如用户可以扩展自定义的函数(函数是可以在测试脚本中插入到任何Sampler或者测试元素中,可以封装一些功能,比如对用户名加解密函数或者得到一个自定义功能等)

首先本文将以Java扩展一个返回两个数值之和函数的例子来简单演示整个过程。总体来说,二次开发扩展JMeter的函数可以分成下面几个步骤:

参考

参考JMeter官方API的AbstractFunction,它将指导我们创建自己的函数 &__7DDemoPlus函数,以便我们了解它是怎么生成的。

创建Java Maven项目

新建一个Maven项目,打开pom.xml,加入ApacheJMeter_functions依赖库

  1.    

  2.        

  3.            org.apache.jmeter

  4.            ApacheJMeter_functions

  5.            4.0

  6.        

  7.    

扩展自定义函数

要实现二次扩展函数,主要有两点:

定义包名

分布式压测怎么做_压测工具jmeter原理_jmeter分布式压测

继承并实现AbstractFunction四个抽象方法:

  1. public class Plus extends AbstractFunction {

  2.    //定义一个obect对象去接受传入变量值

  3.    private Object[] values;

  4.    //存储第一个和第二个参数

  5.    private CompoundVariable first,second;

  6.    /**

  7.     * 执行方法

  8.     * @param sampleResult

  9.     * @param sampler

  10.     * @return

  11.     * @throws InvalidVariableException

  12.     */

  13.    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {

  14.        //接住第一个参数值

  15.        first = (CompoundVariable) values[0];

  16.        //接住第二个参数值

  17.        second = (CompoundVariable) values[1];

  18.        //计算两个参数的和

  19.        int count = new Integer(first.execute().trim()) + new Integer(second.execute().trim());

  20.        System.out.println("两个参数的和是:"+count);

  21.        //返回一个String类型的和

  22.        return String.valueOf(count);

  23.    }

  24.    /**

  25.     * 设置参数,接受用户传递的参数

  26.     * @param collection

  27.     * @throws InvalidVariableException

  28.     */

  29.    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {

  30.        //检查参数是否合法

  31.        checkParameterCount(collection,2);

  32.        //转换成数组

  33.        values = collection.toArray();

  34.    }

  35.    /**

  36.     * 函数名称

  37.     * @return

  38.     */

  39.    public String getReferenceKey() {

  40.        return "__7DDemoPlus";

  41.    }

  42.    /**

  43.     * 函数描述,获取参数描述

  44.     * @return

  45.     */

  46.    public List<String> getArgumentDesc() {

  47.        List desc = new ArrayList();

  48.        //界面上显示两行参数描述

  49.        desc.add("第一个数字");

  50.        desc.add("第二个数字");

  51.        return desc;

  52.    }

  53. }

在控制台使用 mvn cleanpackage打包

分布式压测怎么做_压测工具jmeter原理_jmeter分布式压测

拷贝自定义函数包文件到jmeter/lib/ext目录下

分布式压测怎么做_压测工具jmeter原理_jmeter分布式压测

重启Jmeter后打开函数助手,并生成并复制自定义函数表达式

压测工具jmeter原理_jmeter分布式压测_分布式压测怎么做

并使用BeanShell调用自定义函数,并检查结果

压测工具jmeter原理_jmeter分布式压测_分布式压测怎么做

我们可以看到控制台已经正确输出函数结果了

至此,我们的Jmeter扩展函数已经完成了,同学们是不是so easy。。。

实践小例子

目前能实现压测ActiveMQ有以下方法:

接下我们在以上示例的基础实践压测ActiveMQ消息服务

想要了解ActiveMQ是啥,首先得知道JMS,所以先对MOM和JMS做一个介绍

MOM简介

企业消息系统,即面向消息的中间件,提供了以松散耦合的灵活方式集成应用程序的一种机制。它们提供了基于存储和转发的应用程序之间的异步数据发送,即应用程序彼此不直接通信,而是与作为中介的MOM通信。

JMS简介

Java Message Service:是Java平台上有关面向消息中间件的技术规范。

有一个比较通俗的解释,JMS类似于JDBC,JDBC是可以用来访问许多不同关系数据库的API,而JMS则提供同样与厂商无关的访问的API,以访问消息收发服务。比如IBM的MQSeries、BEA的WeblogicJMSservice;而ActiveMQ也是其中的一种,所以:activeMQ就是支持jms规范的一个server;它对于JDBC和数据库的关系来说,它就是个mysql(MQSeries就是DB2,WeblogicJMSservice就是Oracle)。

在没有JDBC之前,程序员需要访问数据库的时候,需要根据不同的数据库进行不同的编码;在有了JDBC之后,开发过程中,对于不同数据库的访问方法被规范化,只需要根据不同的数据库使用不同的数据库驱动,就可以用通用的方法访问数据库。

在没有JMS之前,程序员开发过程中,如果需要和MOM进行消息发送或接受的时候,需要根据不同的MOM进行不同的编码;相同的,有了JMS之后,代码被规范使用。

ActiveMQ简介

ActiveMQ是目前最流行的消息中间件之一,是一种在分布式系统中应用程序借以传递消息的媒介,常见的消息中间有ActiveMQ,RabbitMQ,Kafka。ActiveMQ是Apache下的开源项目,完全支持JMS1.1和JSE1.4规范的JMS Provider实现

特点:

消息形式:

新建一个消费者maven工程

加入依赖库

  1.        

  2.            org.apache.activemq

  3.            activemq-pool

  4.            5.15.4

  5.        

  6.        

  7.            org.slf4j

  8.            slf4j-log4j12

  9.            1.7.25

  10.        

  11.        

  12.            org.apache.logging.log4j

  13.            log4j-api

  14.            2.11.1

  15.        

  16.        

  17.            org.apache.logging.log4j

  18.            log4j-core

  19.            2.11.1

  20.        

  21.    

实现消费者代码类,这里我们使用Queue的消息形式

  1. Public class Receiver {

  2.    private static final Logger logger = LogManager.getLogger(Receiver.class);

  3.    public static void main(String[] args) {

  4.        //连接工厂,JMS用它创建连接

  5.        ConnectionFactory connectionFactory;

  6.        //JMS client到JMS Provider的连接

  7.        Connection connection = null;

  8.        //一个发送或接受消息的线程

  9.        Session session;

  10.        //消息的目的地,消息发送谁

  11.        Destination destination;

  12.        //消费者,消息接受者

  13.        MessageConsumer consumer;

  14.        connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.5:61616");

  15.        try {

  16.            //构造从工厂得到连接对象

  17.            connection = connectionFactory.createConnection();

  18.            //启动

  19.            connection.start();

  20.            //获取操作连接

  21.            session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

  22.            //获取session的注意参数值,7DQueue是一个消息服务器的队列

  23.            destination = session.createQueue("7DQueue");

  24.            consumer = session.createConsumer(destination);

  25.            while (true) {

  26.                //设置接收者接收消息的时间

  27.                TextMessage message = (TextMessage) consumer.receive(500000);

  28.                if (null != message) {

  29.                    logger.info("收到消息:" + message.getText());

  30.                } else {

  31.                    break;

  32.                }

  33.            }

  34.        } catch (Exception e) {

  35.            e.printStackTrace();

  36.        } finally {

  37.            try {

  38.                if (null != connection)

  39.                    connection.close();

  40.            } catch (Throwable ignore) {

  41.            }

  42.        }

  43.    }

  44. }

新建一个扩展ActiveMQByJmeter maven工程

导入ApacheJMeter_functions依赖库及ActiveMQ相关依赖库

  1.        

  2.            org.apache.jmeter

  3.            ApacheJMeter_functions

  4.            4.0

  5.        

  6.        

  7.            org.apache.activemq

  8.            activemq-pool

  9.            5.15.4

  10.        

  11.        

  12.            org.slf4j

  13.            slf4j-log4j12

  14.            1.7.25

  15.        

  16.        

  17.            org.apache.logging.log4j

  18.            log4j-api

  19.            2.11.1

  20.        

  21.        

  22.            org.apache.logging.log4j

  23.            log4j-core

  24.            2.11.1

  25.        

  26.    

实现生产者代码类

  1. public class Producer {

  2.    private static final Logger logger = LogManager.getLogger(Producer.class);

  3.    public void producer(String brokerURL,String Queue,String message) {

  4.        //连接工厂,JMS使用它创建连接

  5.        ConnectionFactory connectionFactory;

  6.        //Provider的连接

  7.        Connection connection = null; //JMS客户端到JMS

  8.        Session session; //一个发送和接受消息的线程

  9.        Destination destination; //消息的目的地,消息发给谁

  10.        MessageProducer producer; //消息发送者

  11.        //构造连接工厂实例对象

  12.        connectionFactory = new ActiveMQConnectionFactory(brokerURL);

  13.        try {

  14.            //构造从工厂得到连接对象

  15.            connection = connectionFactory.createConnection();

  16.            //启动

  17.            connection.start();

  18.            //获取操作连接

  19.            session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

  20.            //获取session,注意指定消息队列

  21.            destination = session.createQueue(Queue);

  22.            //得到消息生产者(发送者)

  23.            producer = session.createProducer(destination);

  24.            //设置消息持久化方式

  25.            producer.setDeliveryMode(DeliveryMode.PERSISTENT);

  26.            //构造消息,此处写死,项目就是参数,或者方法获取

  27.            //发送消息到目的地方

  28.            TextMessage textMessage = session.createTextMessage("ActiveMq 发送的消息" + message );

  29.            logger.info("发送消息:" + "ActiveMq 发送的消息" + message);

  30.            producer.send(textMessage);

  31.            session.commit();

  32.        } catch (Exception e) {

  33.            e.printStackTrace();

  34.        } finally {

  35.            try {

  36.                if (null != connection)

  37.                    connection.close();

  38.            } catch (Throwable ignore) {

  39.            }

  40.        }

  41.    }

  42. }

编写一个RunMian测试类

  1. public class RunMain {

  2.    public static void main(String[] args) {

  3.        new Producer().producer

  4.                ("tcp://192.168.1.5:61616","7DQueue","7DTest...");

  5.    }

  6. }

运行RunMian发送消息,查看消费端接受情况

我们看到消费端已经收到消息,测试成功

接下来扩展实现JmeterActiveMQFunction

  1. public class ActiveMQFunction extends AbstractFunction{

  2.    //定义一个obect对象去接受传入变量值

  3.    private Object[] values;

  4.    //存储三个参数

  5.    private CompoundVariable brokerURL,Queue,message;

  6.    /**

  7.     * 执行方法

  8.     * @param sampleResult

  9.     * @param sampler

  10.     * @return

  11.     * @throws InvalidVariableException

  12.     */

  13.    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {

  14.        //接住服务地址URL参数值

  15.        brokerURL = (CompoundVariable) values[0];

  16.        //接住消息队列参数值

  17.        Queue = (CompoundVariable) values[1];

  18.        //接住消息内容参数值

  19.        message = (CompoundVariable) values[2];

  20.        //把参数类型转成字符串

  21.        String strBrokerURL = brokerURL.execute().toString();

  22.        String strQueue = Queue.execute().toString();

  23.        String strMessage = message.execute().toString();

  24.        //指定目的地,发送消息

  25.        new Producer().producer(strBrokerURL,strQueue,strMessage);

  26.        //返回值

  27.        return null;

  28.    }

  29.    /**

  30.     * 设置参数,接受用户传递的参数

  31.     * @param collection

  32.     * @throws InvalidVariableException

  33.     */

  34.    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {

  35.        //检查参数是否合法

  36.        checkParameterCount(collection,3);

  37.        //转换成数组

  38.        values = collection.toArray();

  39.    }

  40.    /**

  41.     * 函数名称

  42.     * @return

  43.     */

  44.    public String getReferenceKey() {

  45.        return "__7DGroupActiveMQ";

  46.    }

  47.    /**

  48.     * 函数描述,获取参数描述

  49.     * @return

  50.     */

  51.    public List<String> getArgumentDesc() {

  52.        List desc = new ArrayList();

  53.        //界面上显示三行参数描述

  54.        desc.add("服务地址");

  55.        desc.add("消息队列");

  56.        desc.add("消息内容");

  57.        return desc;

  58.    }

  59. }

在控制台使用 mvn cleanpackage打包测试类

使用 mvn dependency:copy-dependencies-DoutputDirectory=lib复制所依赖的jar包都会到项目下的lib目录下

分布式压测怎么做_压测工具jmeter原理_jmeter分布式压测

复制测试代码Jar包到jmeterlibext目录下,复制依赖包到jmeterlib目录下

重启Jmeter后打开函数助手,并生成并复制自定义函数表达式,使用 __Random函数对消息内容简单参数化

分布式压测怎么做_压测工具jmeter原理_jmeter分布式压测

下面我们将进行性能压测,设置线程组,设置5个并发线程。定义并使用BeanShell调用自定义函数

分布式压测怎么做_压测工具jmeter原理_jmeter分布式压测

我们可以看到消费端已经接收到消息


创业/副业必备:

本站已持续更新1W+创业副业顶尖课程,涵盖多个领域。

点击查看详情

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。