Dubbo服务测试集成Jmeter(二)

本文介绍如何将Dubbo服务测试集成到Jmeter中,包括通过代码封装命令行请求,利用Zookeeper获取服务提供者IP,以及在Jmeter中通过BeanShell取样器和Java请求调用自定义的测试工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Dubbo服务测试方法介绍(一)
通过上篇文章介绍了Dubbo接口测试通过命令的方式进行请求测试。这篇文章主要介绍将命令行请求的方式通过代码封装,集成到Jmeter中、接口平台中,形成工具可以在工作中随手即用。

代码

上篇文章中我们是根据dubbo提供者部署服务器地址进行访问的,当我们的服务通过docker或其他容器部署时,每次部署ip会进行改变,这时就需要zookeeper注册中心实时获取提供者ip,然后进行测试。所以此次代码中获取提供者ip通过zookeeper注册中心实时获取。

这篇文章主要讲解集成Jmeter,所以需要创建java project项目。不过代码逻辑是统一的,后续如果想要集成到平台中,可以将代码集成到springBoot项目中去,通过接口进行自动化方面的测试集成。

第一步:创建java project工程项目

在这里插入图片描述

第二步:编写代码完成后,打成jar包,将jar包copy到jmeter的{Jmeter_home}\lib\ext文件夹下

在这里插入图片描述
通过Jmeter调用自定义Jar时,有多种方式,其中一个是通过BeanShell取样器编写代码调用,另一种方式是通过Java请求的方式调用(推荐)如下图:
在这里插入图片描述

代码(BeanShell取样器调用)
package com.juzi.zk;

import org.I0Itec.zkclient.ZkClient;
import org.apache.commons.net.telnet.TelnetClient;

import java.io.InputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

/**
 * @ClassName DubboTest
 * @Description TODO
 * @Author wangxiaowu
 * @Date 2021/5/10 17:41
 * @Version 1.0
 */
public class DubboTest {

    private static ZkClient zkClient = null;
    private static TelnetClient telnet;
    private static InputStream in;        // 输入流,接收返回信息
    private static PrintStream out;    // 向服务器写入 命令
    private static String prompt = ">";    //结束标识字符串,Windows中是>,Linux中是#
    private static char promptChar = '>';    //结束标识字符

    public static void main(String[] args) {
        String res = DubboTest.sendRequest("1.1.1.1:2181", "provider-test",
                "com.aa.bb.ProductRemoteService",
                "getProductProperty",
                "{\"application\":\"aa\"}");
        System.out.println(res);
    }

    public static String sendRequest(String conn,String applicationName,String service,String methods,String params){
        // 判断zkClient是否为null,为null创建对象否则使用
        if (zkClient==null){
            zkClient =  new ZkClient(conn,100000 );
            telnet = new TelnetClient("VT220");
            setPrompt(">");
        }
        // 此方法是通过zookeeper注册中心获取服务提供者部署机器的ip,返回格式为192.1.5.121:20780
        String dubboConn = getDubboConn(service, applicationName);
        // 字符串分割ip与端口,方便之后invoke命令行请求时调用
        String[] split = dubboConn.split(":");
        //拼接命令
        String command = "invoke " + service + "." + methods + "(" + params + ")";
        // 调用命令行模式发送dubbo请求,并返回结果
        String res = sendDubbo(split[0], Integer.parseInt(split[1]), command);
        // 命令行请求dubbo后返回内容会带相关命令字符,通过截取只将返回结果返回,其他字符祛除
        String[] str = res.split("\r\n");
        return str[0];
    }

    public static void setPrompt(String prompt) {
        if (prompt != null) {
            prompt = prompt;
            promptChar = prompt.charAt(prompt.length() - 1);
        }
    }

    public static String getDubboConn(String service, String applicationName){
        // 定义变量用来保存唯一符合服务的变量
        String path = null;
        // 根据传入的服务名获取zookeeper中心提供此服务所有环境的提供者列表
        List<String> list = zkClient.getChildren("/dubbo/"+service+"/providers"); // 获取此节点下的服务提供者
        // 循环所有的提供者,根据应用名称获取想要的唯一值
        for(String str : list){
            try {
                if (str.contains(applicationName)&&!str.contains("acm-provider-test2")){
                    path = java.net.URLDecoder.decode(str, "UTF-8");
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        // 获取ip
        URI uri = null;
        String ipPort = null;
        try {
            uri = new URI(path);
            ipPort = uri.getHost()+":"+uri.getPort();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return ipPort;
    }

    public static void login(String ip, int port) {
        try {
            telnet.connect(ip, port);
            in = telnet.getInputStream();
            out = new PrintStream(telnet.getOutputStream());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void write(String value) {
        try {
            out.println(value);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String readUntil(String pattern) {
        StringBuffer sb = new StringBuffer();
        try {
            char lastChar = (char) -1;
            boolean flag = pattern != null && pattern.length() > 0;
            if (flag)
                lastChar = pattern.charAt(pattern.length() - 1);
            char ch;
            int code = -1;
            while ((code = in.read()) != -1) {
                ch = (char) code;
                sb.append(ch);

                //匹配到结束标识时返回结果
                if (flag) {
                    if (ch == lastChar && sb.toString().endsWith(pattern)) {
                        return sb.toString();
                    }
                } else {
                    //如果没指定结束标识,匹配到默认结束标识字符时返回结果
                    if (ch == promptChar)
                        return sb.toString();
                }
                //登录失败时返回结果
                if (sb.toString().contains("Login Failed")) {
                    return sb.toString();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
    public static String sendCommand(String command) {
        try {
            write(command);
            return readUntil(prompt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String sendDubbo(String ip, int port, String cmd) {
        /**
         * ls
         * ls RepayPlanRemoteService
         * invoke RepayPlanRemoteService.trial("+params+")
         */
        login(ip, port);
        String rs = sendCommand(cmd);
        try {
            rs = new String(rs.getBytes("ISO-8859-1"), "GBK");    //转一下编码
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return rs;
    }
}

代码(Java请求调用)
package com.juzi.zk;

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;

/**
 * @ClassName DubboJmeter
 * @Description TODO
 * @Author wangxiaowu
 * @Date 2021/5/11 9:51
 * @Version 1.0
 */
public class DubboJmeter extends AbstractJavaSamplerClient {

    /**
     * 定义变量,赋值Jmeter中java请求时传入的参数
     */
    String dubboConn = "";
    String applicationName = "";
    String serviceClassPatn = "";
    String serviceMethods = "";
    String serviceParams = "";

    /**
     * 用来自定义参数的方法,Jmeter中的java请求取样器中的入参定义方法
     * 每个线程测试前执行一次,做一些初始化工作
     * @return
     */
    @Override
    public Arguments getDefaultParameters() {
        // 创建自定义参数的对象
        Arguments params = new Arguments();
        // zookeeper注册中心地址,ip及端口的拼接
        params.addArgument("dubboConn", "1.1.1.1:2181");
        // 提供者的应用名称
        params.addArgument("applicationName", "acm-e-test");
        // dubbo请求的service的路径
        params.addArgument("serviceClassPatn", "com.a.b.c.r");
        // dubbo请求的service的方法
        params.addArgument("serviceMethods", "a");
        // dubbo请求的service的请求参数
        params.addArgument("serviceParams", "{\"application\":\"q\"}");

        return params;
    }

    /**
     * 获取参数的方法,用来获取Jmeter中传入的参数
     * @param context
     */
    @Override
    public void setupTest(JavaSamplerContext context) {
        dubboConn = context.getParameter("dubboConn");
        applicationName = context.getParameter("applicationName");
        serviceClassPatn = context.getParameter("serviceClassPatn");
        serviceMethods = context.getParameter("serviceMethods");
        serviceParams = context.getParameter("serviceParams");
    }

    /**
     * Jmeter中的请求主体,jmeter请求时运行的主要逻辑则为此方法
     * @param javaSamplerContext
     * @return
     */
    @Override
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        //new一个SampleResult对象,用来实现计时、结果回写等操作。
        SampleResult sr=new SampleResult();
        // try...catch,捕获一下异常
        try {
            //请求开始计时
            sr.sampleStart();
            // 调用通过zookeeper注册中心请求dubbo的方法并返回结果
            String res = DubboTest.sendRequest(dubboConn, applicationName, serviceClassPatn, serviceMethods, serviceParams);
            // 设置显示请求数据
            sr.setSamplerData("本次请求参数 :\n注册中心:"+dubboConn+"\n请求路径:"+serviceClassPatn+"\n请求方法:"+serviceMethods+"\n请求参数:"+serviceParams);
            // 设置显示数据
            sr.setResponseData(res,null);
            //设置请求的结束状态。
            sr.setSuccessful(true);
        }catch (Exception e){
            sr.setResponseData("fail msg:"+e.getMessage(),sr.TEXT);
            sr.setSuccessful(false);
        }finally {
            //请求结束计时。
            sr.sampleEnd();
        }
        return sr;
    }
}

Jmeter中Beanshell取样器的演示

将工程项目打成jar导入到jmeter指定目录后,打开Jmeter——>添加线程组——>添加Beanshell取样器,如图:
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Jmeter中Java请求的演示

如果第三方jar包想使用Jmeter中的Java请求的方式调用,需要将Jmeter目录中{jmeter_home}\lib\ext的ApacheJMeter_core.jar、ApacheJMeter_java.jar两个jar包导入到项目工程中。
在这里插入图片描述

将工程项目打成jar导入到jmeter指定目录后,打开Jmeter——>添加线程组——>添加Java请求,如图:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

至此Dubbo接口测试集成到Jmeter结束…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓 5

有啥不懂的可以单聊解答....

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值