一、 測試腳本編寫
腳本可參考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>
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>
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)+"個文件合並成功!")
四、 常見問題處理
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讀取中文顯示問號的問題
解決辦法:腳本中對要輸出的對象進行強制轉換