• 使用jmeter对dubbo接口进行性能测试教程及常见问题处理


    一、   测试脚本编写

    脚本可参考git项目: https://github.com/aland-1415/dubbo-interface-test.git

    1、 pom依赖

    (注意添加的jmeter版本要与运行时使用的版本一致,这里使用的是3.1版本)    

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.7</maven.compiler.source>
            <maven.compiler.target>1.7</maven.compiler.target>
            <spring.version>4.3.5.RELEASE</spring.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.jmeter</groupId>
                <artifactId>ApacheJMeter_core</artifactId>
                <version>3.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-all</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>commons-math3</groupId>
                        <artifactId>commons-math3</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>commons-pool2</groupId>
                        <artifactId>commons-pool2</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.jmeter</groupId>
                <artifactId>ApacheJMeter_java</artifactId>
                <version>3.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-math3</groupId>
                        <artifactId>commons-math3</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>commons-pool2</groupId>
                        <artifactId>commons-pool2</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.5.3</version>
                <exclusions>
                    <exclusion>
                        <artifactId>spring</artifactId>
                        <groupId>org.springframework</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.3</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!--添加业务的jar包依赖-->
    
            <!--压测接口所需要的包-->
            <dependency>
                <groupId>com.dmall</groupId>
                <artifactId>rcs-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
        <build>
                <plugins>
                    <!--复制jar包插件,将使用到的jar包,复制到target/lib中-->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-dependency-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>copy-dependencies</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>copy-dependencies</goal>
                                </goals>
                                <configuration>
                                    <outputDirectory>target/lib</outputDirectory>
                                    <overWriteReleases>false</overWriteReleases>
                                    <overWriteSnapshots>false</overWriteSnapshots>
                                    <overWriteIfNewer>true</overWriteIfNewer>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
    
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>build-helper-maven-plugin</artifactId>
                        <version>1.8</version>
                        <executions>
                            <execution>
                                <id>add-resource</id>
                                <phase>generate-resources</phase>
                                <goals>
                                    <goal>add-resource</goal>
                                </goals>
                                <configuration>
                                    <resources>
                                        <resource>
                                            <directory>src/main/resources</directory>
                                            <includes>
                                                <include>*</include>
                                            </includes>
                                        </resource>
                                    </resources>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
    
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <!--设置自动替换-->
            </resources>
    
        </build>
    pom.xml

    2、 dubbo服务配置(dubbo-config.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://code.alibabatech.com/schema/dubbo
            http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            ">
    
        <dubbo:application name="dmall-performance-test " owner="dmalltest"  />
    
        <!-- 线上环境     注册中心暴露发现服务地址 -->
        <!-- 
        <dubbo:registry address="zookeeper://192.168.90.148:2181?backup=192.168.90.149:2181,192.168.90.150:2181"/>
         -->
    
        <!-- 测试环境     注册中心暴露发现服务地址,测试脚本使用 -->
        <!-- 
        <dubbo:registry address="zookeeper://testzk1.dmall.com:2181?backup=testzk2.dmall.com:2181,testzk3.dmall.com:2181,testzk4.dmall.com:2181,testzk5.dmall.com:2181"/>
         -->
    
        <!-- dev环境     注册中心暴露发现服务地址,编写脚本调试使用 -->
        <dubbo:registry address="zookeeper://devzk1.dmall.com:2181?backup=devzk2.dmall.com:2181,devzk3.dmall.com:2181"/>
    
        <!--<dubbo:registry address="${dubbo.zookeeper.address }"/> -->
    
    
        <!--erp系统接口接口压测-->
        <dubbo:reference id="recServer" interface="com.dmall.rcs.api.RcsServer" timeout="10000" check="false"/>
    
    </beans>
    dubbo-config.xml

    3、 接口测试代码

     1 public class RcsServerTest implements JavaSamplerClient {//也可继承 AbstractJavaSamplerClient
     2     
     3     ApplicationContext context = new ClassPathXmlApplicationContext("dubbo-config.xml");
     4     RcsServer recServer=(RcsServer) context.getBean("recServer");
     5     long start = 0, end = 0;
     6     
     7     //运行runTest方法前会调用此方法
     8     @Override
     9     public void setupTest(JavaSamplerContext argv0) {
    10         start = System.currentTimeMillis();
    11     }
    12     
    13     //Jmeter界面手工输入的参数,可以在此方法中获取
    14     @Override
    15     public Arguments getDefaultParameters() {
    16           Arguments args = new Arguments();
    17           args.addArgument("primaryKey", "165987729026");
    18           args.addArgument("useType", "post_order");
    19           args.addArgument("businessDate", "2019-10-14 00:00:05");
    20           args.addArgument("userId", "96322526");
    21           args.addArgument("clientIp", "183.228.99.149");
    22           return args;
    23     }
    24     
    25     //接口测试代码
    26     @Override
    27     public SampleResult runTest(JavaSamplerContext arg0) {
    28         String sys = arg0.getParameter("sys", "test");//arg0是运行jmeter时传的参数
    29         String primaryKey = arg0.getParameter("primaryKey");
    30         String useType = arg0.getParameter("useType");
    31         String businessDateStr = arg0.getParameter("businessDate");
    32         String userId = arg0.getParameter("userId");
    33         String clientIp = arg0.getParameter("clientIp");
    34         String exParameterStr = arg0.getParameter("exParameter");        
    35         RcsRequest rcsRequest = new RcsRequest(sys, primaryKey, useType, businessDate, userId, clientIp, exParameter);        
    36         
    37         SampleResult sr = new SampleResult();
    38         sr.setSamplerData("系统RecServer测试");
    39         //jmeter开始计响应时间标记
    40         sr.sampleStart();
    41         
    42         //调用被测试接口
    43         RcsResponse response = recServer.discern(rcsRequest);
    44         
    45         try {
    46             sr.setSuccessful(true);
    47             //jmeter最后显示的响应结果
    48             sr.setResponseData("风险系数:" + response.getRiskScore());
    49             sr.sampleEnd();
    50         } catch (Exception e) {
    51             sr.setSuccessful(false);
    52             e.printStackTrace();
    53         }
    54         
    55         //结束计响应时间标记
    56         sr.sampleEnd();
    57         return sr;
    58     }
    59 
    60     //运行runTest方法后会调用此方法
    61     @Override
    62     public void teardownTest(JavaSamplerContext context) {    
    63         end = System.currentTimeMillis();
    64         System.out.println("cost time: " + (end - start));
    65     }
    66     
    67     //用于开发时直接运行调试用
    68     public static void main(String[] args){
    69         RcsServerTest test = new RcsServerTest();
    70         Arguments params = test.getDefaultParameters();
    71         JavaSamplerContext arg0 = new JavaSamplerContext(params); 
    72         test.setupTest(arg0);
    73         test.runTest(arg0);
    74     }
    75 }

    注意:最终输出jar包时,要确保取样周期内,没有不相干的输出操作。否则,会影响【响应时间】统计数据的准确性

    4、打包

    (注意是打jar包,这个需要在pom文件里配置<packaging>jar</packaging>)

    项目结构:

     

    dubbo.xsd 文件下载地址: https://github.com/alibaba/dubbo

    方法一:mvn clean -Ptest install

    将  “项目路径/target” 下生成的jar包拷贝到 “jmeter安装目录/lib/ext”

    将  “项目路径/target/lib” 下所有的依赖jar包拷贝到 “jmeter安装目录/lib”

    方法二:用Eclipse的export导出可执行的jar包文件

     

      

     将生成的jar包及同名文件夹一起拷贝到 “jmeter安装目录/lib/ext”

    二、   在jmeter上运行脚本

    1、 编写jmeter脚本

    (1)     添加线程组

     

    (2)     添加java请求

     

    (3)     选择测试接口

     

    (4)     保存

    2、 非GUI运行脚本命令

    sudo sh  jmeter安装目录/bin/jmeter.sh -n -t test.jmx -l result.jtl

    test.jmx是jmeter脚本

    result.jtl 是最后存放测试结果的文件 

    :linux上测试时可使用dstat 命令,可实时监控服务器CPU、磁盘、网络等基本情况

    三、   压测报告生成

    ./jmeter安装目录/bin/jmeter.sh -g result.jtl -e -o resultReport

    最后生成的报告是html存放于resultReport文件中,打开index.html即可

    也可以在运行测试命令时同时加报告生成命令:

    sudo sh  jmeter安装目录/bin/jmeter.sh -n -t test.jmx -l result.jtl -e -o resultReport 

    附:

    #coding=utf-8
    
    import os
    
    def mergeJTL(filedir):
        filenames=os.listdir(filedir)
        f=open('result.jtl','w',encoding='utf-8')
        #文件计数器
        num=0
        for filename in filenames:
            if filename=="result.jtl" or filename[-3:]!="jtl":
                pass
            else:
                print("将要开始合并的文件是:"+filename)
                filepath = filedir+'/'+filename
                for line in open(filepath,encoding='utf-8'):
                    lineList=line.split(",")
                    #去除自第二个并入的文件开始的首行文字内容
                    if num!=0 and "timeStamp" in line:
                        pass
                    #去除数据不为16列或17列的
                    elif len(lineList)!=16 and len(lineList)!=17:
                        pass
                    #去除每行第一列不为13位时间戳的数据
                    elif num!=0 and len(lineList[0])!=13:
                        pass                
                    else:
                        f.writelines(line)
                num=num+1
        f.close()
        print(str(num)+"个文件合并成功!")
    用于手动合并jtl文件脚本

    四、   常见问题处理

    1、 注意所有的路径不要包含中文;

    2、 许多打开jmeter就报错可能是因为引用的jar包与jmeter已有的jar冲突了且版本不一致,可删除其中重复的jar包或者把两边jar包的版本号修改为相同的

    3、 导出的jar包放到jmeter的lib/ext目录下,创建测试计划->创建线程组->创建java请求,找不到编写的方法;

    问题原因:编写java脚本时,jdk的版本使用的是1.8,而本机jmeter使用的是1.7

    解决办法:2边jdk版本修改一致

    4、 从jmeter读取中文显示问号的问题

    解决办法:脚本中对要输出的对象进行强制转换

  • 相关阅读:
    使用nodejs运行SAP Fiori应用
    JUnit 注解@Rule的工作原理
    JUnit 注解@SuiteClasses的工作原理
    JUnit 注解@Category的工作原理
    JUnit 注解@RunWith的工作原理
    Eclipse里如果看不到Attach Source按钮应该怎么办
    使用SAP CRM中间件从ERP下载BOM的一些常见问题
    GaussDB(DWS):非侵入式备份及其在NBU上的应用
    华为云原生数据仓库GaussDB(DWS)深度技术解读:融、快、大、稳、易
    华为云举办AI经典论文复现活动,打造领先AI开发者学习社区
  • 原文地址:https://www.cnblogs.com/aland-1415/p/11694203.html
Copyright © 2020-2023  润新知