Jmeter-基础篇
常用壓力測試工具對比
?? ??? ?1、loadrunner
?? ??? ??? ?性能穩(wěn)定,壓測結(jié)果及細(xì)粒度大,可以自定義腳本進(jìn)行壓測,但是太過于重大,功能比較繁多
?? ??? ?2、apache ab(單接口壓測最方便)
?? ??? ??? ?模擬多線程并發(fā)請求,ab命令對發(fā)出負(fù)載的計算機要求很低,既不會占用很多CPU,也不會占用太多的內(nèi)存,但卻會給目標(biāo)服務(wù)器造成巨大的負(fù)載, 簡單DDOS攻擊等
?? ??? ?3、webbench
?? ??? ??? ?webbench首先fork出多個子進(jìn)程,每個子進(jìn)程都循環(huán)做web訪問測試。子進(jìn)程把訪問的結(jié)果通過pipe告訴父進(jìn)程,父進(jìn)程做最終的統(tǒng)計結(jié)果。
Jmeter基本介紹和使用場景
?? ?簡介
?? ??? ?1、壓測不同的協(xié)議和應(yīng)用
?? ??? ??? ?1) Web - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …)
?? ??? ??? ?2) SOAP / REST Webservices
?? ??? ??? ?3) FTP
?? ??? ??? ?4) Database via JDBC
?? ??? ??? ?5) LDAP ?輕量目錄訪問協(xié)議
?? ??? ??? ?6) Message-oriented middleware (MOM) via JMS
?? ??? ??? ?7) Mail - SMTP(S), POP3(S) and IMAP(S)
?? ??? ??? ?8) TCP等等
?? ??? ?2、使用場景及優(yōu)點
?? ??? ??? ?1)功能測試
?? ??? ??? ?2)壓力測試
?? ??? ??? ?3)分布式壓力測試
?? ??? ??? ?4)純java開發(fā)
?? ??? ??? ?5)上手容易,高性能
?? ??? ??? ?4)提供測試數(shù)據(jù)分析
?? ??? ??? ?5)各種報表數(shù)據(jù)圖形展示
本地快速安裝Jmeter4.x
apache jmeter是100%的java桌面應(yīng)用程序,它被設(shè)計用來加載被測試軟件功能特性、度量被測試軟件的性能。設(shè)計jmeter的初衷是測試web應(yīng)用,后來又?jǐn)U充了其它的功能。jmeter可以完成針對靜態(tài)資源和動態(tài)資源(servlets, perl腳本, java對象, 數(shù)據(jù)查詢s, ftp服務(wù)等)的性能測試。 jmeter可以模擬大量的服務(wù)器負(fù)載、網(wǎng)絡(luò)負(fù)載、軟件對象負(fù)載,通過不同的加載類型全面測試軟件的性能。并且jmeter提供圖形化的性能分析。
?? ? 1、需要安裝JDK8。或者JDK9,JDK10
?? ? 2、快速下載
?? ? ?? ?windows: http://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-4.0.zip
?? ? ?? ?mac或者linux:http://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-4.0.tgz
?? ? 3、文檔地址:http://jmeter.apache.org/usermanual/get-started.html
?? ? 4、建議安裝JDK環(huán)境,雖然JRE也可以,但是壓測https需要JDK里面的 keytool工具
?? ?
Jmeter目錄文件講解
?? ?1、目錄
?? ??? ?bin:核心可執(zhí)行文件,包含配置
?? ??? ??? ?jmeter.bat: windows啟動文件:
?? ??? ??? ?jmeter: mac或者linux啟動文件:
?? ??? ??? ?jmeter-server:mac或者Liunx分布式壓測使用的啟動文件
?? ??? ??? ?jmeter-server.bat:mac或者Liunx分布式壓測使用的啟動文件
?? ??? ??? ?jmeter.properties: 核心配置文件
?? ??? ??? ?
?? ??? ?extras:插件拓展的包
?? ??? ?lib:核心的依賴包
?? ??? ??? ?ext:核心包
?? ??? ??? ?junit:單元測試包
Jmeter語言版本中英文切換
?? ?簡介:
?? ??? ?講解怎么改變jmeter的GUI界面語言版本
?? ??? ?1、控制臺修改
?? ??? ??? ?menu -> options -> choose language
?? ??? ?2、配置文件修改?? ?
?? ??? ??? ?bin目錄 -> jmeter.properties
?? ??? ??? ??? ?默認(rèn) #language=en
?? ??? ??? ??? ?改為 language=zh_CN?
使用SpringBoot 2.0快速編寫API測試接口
我們在這里面編寫具體方法:
@Controller @RequestMapping("/alpha") public class AlphaController{...具體方法...}
1、模擬GET請求
?2、模擬POST請求
我們的訪問路徑就是localhost:8080/alpha/...
當(dāng)然,為了大家測試方便,我已經(jīng)部署到服務(wù)器上,地址是:
http://139.9.83.25/alpha/方法的path
我把整個alpha的接口都放來,你們可以照著寫或者按照路徑直接訪問服務(wù)器上的進(jìn)行測試。
package com.now.community.community.controller;/* * * http * get請求 * post請求 * 響應(yīng)ModelAndView * 響應(yīng)(簡單) * json * * */ import ch.qos.logback.core.net.SyslogOutputStream; import com.now.community.community.service.AlphaService; import com.now.community.community.util.CommunityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; import java.util.*;@Controller @RequestMapping("/alpha") public class AlphaController {@Autowiredprivate AlphaService AlphaService;@RequestMapping("/hello")@ResponseBodypublic String sayHello(){return "sfadsfafafadf";}@RequestMapping("/data")@ResponseBodypublic String getData(){return AlphaService.find();}@RequestMapping("/http")public void http(HttpServletRequest request, HttpServletResponse response){System.out.println(request.getMethod());System.out.println(request.getServletPath());Enumeration<String> enumeration=request.getHeaderNames();while(enumeration.hasMoreElements()){String name=enumeration.nextElement();String value=request.getHeader(name);System.out.println(name+":"+value);}System.out.println(request.getParameter("code"));response.setContentType("text/html;charset=utf-8");try(PrintWriter writer = response.getWriter()){writer.write("<h1>橙白站</h1>");} catch (IOException e) {e.printStackTrace();}}//get// /students?current=1&limit=20@RequestMapping(path="/students",method= RequestMethod.GET)@ResponseBodypublic String getStudents(@RequestParam(name="current",required = false,defaultValue = "1") int current,@RequestParam(name="limit",required = false,defaultValue = "10") int limit){System.out.println(current);System.out.println(limit);return "some students";}// /student/123@RequestMapping(path="/student/{id}",method= RequestMethod.GET)@ResponseBodypublic String getStudent(@PathVariable("id") int id){System.out.println(id);return "a student";}//post@RequestMapping(path = "/student",method = RequestMethod.POST)@ResponseBodypublic String saveStudent(String name,int age){System.out.println(name);System.out.println(age);return "success";}//響應(yīng)html數(shù)據(jù)@RequestMapping(path = "/teacher",method = RequestMethod.GET)public ModelAndView getTeacher(){ModelAndView mav=new ModelAndView();mav.addObject("name","張三");mav.addObject("age",30);mav.setViewName("/demo/view");return mav;}//返回模板的地址@RequestMapping(path = "/school",method = RequestMethod.GET)public String getSchool(Model model){model.addAttribute("name","北大");model.addAttribute("age","100");return "/demo/view";}//響應(yīng)json數(shù)據(jù)(異步請求中)//java對象->json字符串-> js對象@RequestMapping(path = "/emp",method = RequestMethod.GET)@ResponseBodypublic Map<String,Object> getEmp(){Map<String,Object> emp=new HashMap<>();emp.put("name","張三");emp.put("age",23);emp.put("salary",8000.00);return emp;}@RequestMapping(path = "/emps",method = RequestMethod.GET)@ResponseBodypublic List<Map<String,Object>> getEmps(){List<Map<String,Object>> list=new ArrayList<>();Map<String,Object>emp=new HashMap<>();emp.put("name","張三");emp.put("age",23);emp.put("salary",8000.00);list.add(emp);emp=new HashMap<>();emp.put("name","李四");emp.put("age",24);emp.put("salary",9000.00);list.add(emp);return list;}@RequestMapping(path = "/cookie/set",method = RequestMethod.GET)@ResponseBodypublic String setCookie(HttpServletResponse httpServletResponse){Cookie cookie=new Cookie("code", CommunityUtil.generateUUID());cookie.setPath("/community/alpha");cookie.setMaxAge(60*10);httpServletResponse.addCookie(cookie);return "set cookie";}@RequestMapping(path = "/cookie/get",method = RequestMethod.GET)@ResponseBodypublic String getCookie(@CookieValue("code") String code){System.out.println(code);return "get cookie";}@RequestMapping(path = "/session/set", method = RequestMethod.GET)@ResponseBodypublic String setSession(HttpSession session){session.setAttribute("id",1);session.setAttribute("name","Test");return "set session";}@RequestMapping(path = "/session/get", method = RequestMethod.GET)@ResponseBodypublic String getSession(HttpSession session) {System.out.println(session.getAttribute("id"));System.out.println(session.getAttribute("name"));return "get session";}@RequestMapping(path = "/ajax",method = RequestMethod.POST)@ResponseBodypublic String testAjax(String name,int age){System.out.println(name);System.out.println(age);return CommunityUtil.getJSONString(0,"操作成功");} }?
創(chuàng)建Jmeter測試計劃,快速壓測一個接口
?
我們首先創(chuàng)建一個測試計劃
設(shè)置測試計劃
我們可以創(chuàng)建一個http請求
設(shè)置參數(shù)
解釋一下:
協(xié)議要寫
服務(wù)器名稱或者ip要寫,你可以訪問我的服務(wù)器139.9.83.25,也可以訪問本地localhost前提是你自己啟動了項目。
端口號本地tomcat默認(rèn)8080,如果訪問我的服務(wù)器不用寫,我設(shè)置了。
方法:測什么類型就選什么類型。
路徑:具體接口的路徑
其他的以后再解釋。
?
好,我們run就算測完了,但是看不到結(jié)果,所以繼續(xù)操作
添加結(jié)果樹
查看結(jié)果樹
這是我上面的接口里寫的
Jmeter基礎(chǔ)功能組件介紹線程組和Sampler
?? ??? ?
?? ??? ?1、添加->threads->線程組(控制總體并發(fā))
?? ??? ??? ?線程數(shù):虛擬用戶數(shù)。一個虛擬用戶占用一個進(jìn)程或線程
?? ??? ??? ?
?? ??? ??? ?準(zhǔn)備時長(Ramp-Up Period(in seconds)):全部線程啟動的時長,比如100個線程,20秒,則表示20秒內(nèi)100個線程都要啟動完成,每秒啟動5個線程
?? ??? ??? ?
?? ??? ??? ?循環(huán)次數(shù):每個線程發(fā)送的次數(shù),假如值為5,100個線程,則會發(fā)送500次請求,可以勾選永遠(yuǎn)循環(huán)
? ? ? ? ? ? 調(diào)度器:循環(huán)次數(shù)永遠(yuǎn)之后,可以配置多長時間結(jié)束;也可以配置啟動延遲
?? ??? ??? ?
?? ??? ?2、線程組->添加-> Sampler(采樣器) -> Http (一個線程組下面可以增加幾個Sampler)
?? ??? ??? ?名稱:采樣器名稱
?? ??? ??? ?注釋:對這個采樣器的描述
?? ??? ??? ?web服務(wù)器:
?? ??? ??? ??? ?默認(rèn)協(xié)議是http
?? ??? ??? ??? ?默認(rèn)端口是80
?? ??? ??? ??? ?服務(wù)器名稱或IP :請求的目標(biāo)服務(wù)器名稱或IP地址
?? ??? ??? ?路徑:服務(wù)器URL
?? ??? ??? ?Use multipart/from-data for HTTP POST :當(dāng)發(fā)送POST請求時,使用Use multipart/from-data方法發(fā)送,默認(rèn)不選中。
?? ??? ?3、查看測試結(jié)果
?? ??? ??? ?線程組->添加->監(jiān)聽器->察看結(jié)果樹
Jmeter的斷言基本使用
?
?? ??? ?1、增加斷言: 線程組 -> 添加 -> 斷言 -> 響應(yīng)斷言 ?
?? ??? ??? ?apply to(應(yīng)用范圍):
?? ??? ??? ??? ?Main sample only: 僅當(dāng)前父取樣器 進(jìn)行斷言,一般一個請求,如果發(fā)一個請求會觸發(fā)多個,則就有sub sample(比較少用)
?? ??? ??? ?要測試的響應(yīng)字段:
?? ??? ??? ??? ?響應(yīng)文本:即響應(yīng)的數(shù)據(jù),比如json等文本
?? ??? ??? ??? ?響應(yīng)代碼:http的響應(yīng)狀態(tài)碼,比如200,302,404這些
?? ??? ??? ??? ?響應(yīng)信息:http響應(yīng)代碼對應(yīng)的響應(yīng)信息,例如:OK, Found
?? ??? ??? ??? ?Response Header: 響應(yīng)頭
?? ??? ??? ?模式匹配規(guī)則:
?? ??? ??? ??? ?包括:包含在里面就成功
?? ??? ??? ??? ?匹配:響應(yīng)內(nèi)容完全匹配,不區(qū)分大小寫
?? ??? ??? ??? ?equals:完全匹配,區(qū)分大小寫
舉個例子:
測這個地址:http://139.9.83.25/alpha/emps大家可以先去看一下結(jié)果
我們設(shè)置一下斷言
run后去看結(jié)果樹,肯定是成功的。
但是你改成“相等”,肯定是失敗的
?
?? ??? ??? ??? ?
?? ??? ?2、斷言結(jié)果監(jiān)聽器: 線程組-> 添加 -> 監(jiān)聽器 -> 斷言結(jié)果
?? ??? ??? ?里面的內(nèi)容是sampler采樣器的名稱
?? ??? ??? ?斷言失敗,查看結(jié)果樹任務(wù)結(jié)果顏色標(biāo)紅(通過結(jié)果數(shù)里面雙擊不通過的記錄,可以看到錯誤信息)
點開這個請求可以查看斷言詳情
?? ??? ?3、每個sample下面可以加單獨的結(jié)果樹,然后同時加多個斷言,最外層可以加個結(jié)果樹進(jìn)行匯總
壓測結(jié)果聚合報告分析
?? ?新增聚合報告:線程組->添加->監(jiān)聽器->聚合報告(Aggregate Report)
?? ??? ??? ?lable: sampler的名稱
?? ??? ??? ?Samples: 一共發(fā)出去多少請求,例如10個用戶,循環(huán)10次,則是 100
?? ??? ??? ?Average: 平均響應(yīng)時間
?? ??? ??? ?Median: 中位數(shù),也就是 50% 用戶的響應(yīng)時間
?? ??? ??? ?90% Line : 90% 用戶的響應(yīng)不會超過該時間 (90% of the samples took no more than this time. The remaining samples at least as long as this)
?? ??? ??? ?95% Line : 95% 用戶的響應(yīng)不會超過該時間
?? ??? ??? ?99% Line : 99% 用戶的響應(yīng)不會超過該時間
?? ??? ??? ?min : 最小響應(yīng)時間
?? ??? ??? ?max : 最大響應(yīng)時間
?? ??? ??? ?Error%:錯誤的請求的數(shù)量/請求的總數(shù)
?? ??? ??? ?Throughput: 吞吐量——默認(rèn)情況下表示每秒完成的請求數(shù)(Request per Second) 可類比為qps
?? ??? ??? ?KB/Sec: 每秒接收數(shù)據(jù)量
實戰(zhàn):你可以把路徑換成/,我設(shè)置了弄到主頁,主頁是這個樣子:
這時,有些參數(shù)就可以設(shè)置了:
線程數(shù)請不要超過100,要不然就把我的小服務(wù)器搞炸了。。。
然后run之后可以查看結(jié)果了:
你可以多測幾次,因為可能恰巧系統(tǒng)在垃圾回收,或者在清緩存等等,多測幾次比較準(zhǔn)。
?
Jmeter用戶自定義變量實戰(zhàn)
?
?? ??? ?為什么使用:很多變量在全局中都有使用,或者測試數(shù)據(jù)更改,可以在一處定義,四處使用
?? ??? ?比如服務(wù)器地址
?? ??? ?1、線程組->add -> Config Element(配置原件)-> User Definde Variable(用戶定義的變量)
?? ??? ?
?? ??? ?2、引用方式${XXX},在接口中變量中使用
建議:每個線程組定義自己的。測試計劃定義總的參數(shù),比如網(wǎng)址。
?? ??? ?3、原始查看結(jié)果樹和非原生查看(基礎(chǔ)按鈕)
實戰(zhàn)之CSV可變參數(shù)壓測
?? ??? ?實戰(zhàn)操作jmeter讀取CSV和Txt文本文件里面的參數(shù)進(jìn)行壓測
?? ??? ?1、線程組->add -> Config Element(配置原件)-> CSV data set config (CSV數(shù)據(jù)文件設(shè)置)
參數(shù)太容易理解,不解釋了。
我們可以讀取文件的數(shù)據(jù)進(jìn)行壓測,比如:
一行一個請求,很容易理解吧。
你會發(fā)現(xiàn)user是變化的。
介紹多參數(shù)分隔符:
你可以設(shè)置分隔符:
然后就可以使用了:
唉。。。截圖截到現(xiàn)在。。實在是不i想截了,數(shù)據(jù)庫我就不截圖了。。。只有步驟和參數(shù)解釋
JDBC request壓測Mysql
講解jdbc壓測mysql相關(guān)準(zhǔn)備工作,jar包添加,配置講解
?? ??? ?1、Thread Group -> add -> sampler -> jdbc request
?? ??? ?2、jar包添加 ?mysql-connector-java-5.1.30.jar?
?? ??? ?3、JDBC connection Configuration 配置
?? ??? ??? ?1、JDBC request->add -> config element -> JDBC connection configuration
?? ??? ??? ??? ?核心配置
?? ??? ??? ??? ??? ?Max Number of connections : 最大連接數(shù)
?? ??? ??? ??? ??? ?MAX wait :最大等待時間
?? ??? ??? ??? ??? ?Auto Commit: 是否自動提交事務(wù)
?? ??? ??? ??? ??? ?DataBase URL : 數(shù)據(jù)庫連接地址 jdbc:mysql://127.0.0.1:3306/blog
?? ??? ??? ??? ??? ?JDBC Driver Class : 數(shù)據(jù)庫驅(qū)動,選擇對應(yīng)的mysql
?? ??? ??? ??? ??? ?username:數(shù)據(jù)庫用戶名
?? ??? ??? ??? ??? ?password:數(shù)據(jù)庫密碼
JDBC request壓測Mysql, select
?? ?使用jmeter壓測mysql,select,insert語句
?? ??? ?1、Debug Sampler使用(結(jié)果樹中查看)
?? ??? ??? ?Thread Group -> add -> sampler -> debug sampler
?? ??? ??? ?
?? ??? ?2、參數(shù)講解:(sql結(jié)尾不要加";")
?? ??? ??? ?1、variable name of pool declared in JDBC connection configuration(和配置文件同名)
?? ??? ??? ?2、Query Type 查詢類型
?? ??? ??? ?3、parameter values 參數(shù)值
?? ??? ??? ?4、parameter types ?參數(shù)類型
?? ??? ??? ?5、variable names ?sql執(zhí)行結(jié)果變量名
?? ??? ??? ?6、result variable names 所有結(jié)果當(dāng)做一個對象存儲
?? ??? ??? ?7、query timeouts ?查詢超時時間?
?? ??? ??? ?8、 handle results ?處理結(jié)果集
定時器
定時器幫助我們模擬更真實的場景
隨機多長時間,這也比較符合我們真實的場景,肯定是有不確定間隔的請求過來。
其他的定時器做到見文知意。
執(zhí)行順序
1.配置元件 2.前置處理程序 3.定時器 4.sampler 5.后置處理程序 6.斷言 7.監(jiān)聽器如果在同一個作用域范圍內(nèi)有多個同一類型的元件,則這些元件按照它們在測試計劃中的上下順序依次執(zhí)行
作用域
?固定定時器:http1
?循環(huán)控制器:http2、http3、圖形結(jié)果、隨機控制器
?圖形結(jié)果:http2、http3
?響應(yīng)斷言:jdbc
?聚合報告:所有
?
for-each控制器
目的:遍歷變量值
一般和用戶自定義變量(User Defined Variables)一起使用,其在用戶自定義變量中讀取一系列相關(guān)的變量。每一個線程下執(zhí)行時該控制器下的采樣器或控制器都會被執(zhí)行一次或多次(次數(shù)和用戶變量有關(guān))。輸入應(yīng)包括的幾個變量,每個變量由變量名、下劃線、和數(shù)字組成,每個變量必須有一個值
switch控制器
該控制器可以控制里面的請求根據(jù)某些規(guī)則,在不同數(shù)字時選擇控制器下的對應(yīng)數(shù)字位的不同sampler。一般可以用在模擬多線程同時操作不同請求的測試場景。
Switch Value:設(shè)置你要訪問的請求索引(從0開始的)或者直接設(shè)置訪問的請求名稱。數(shù)字對應(yīng)的就是每個請求的順序(注意點:第一個是0),這個num可以通過計數(shù)器,counter函數(shù),random函數(shù)來自動生成(一般常用random函數(shù))。
if控制器
目的:判斷條件,可以引用變量。當(dāng)為 true 時,執(zhí)行相應(yīng)的操作
Interpret Condition as Variable Expression?
如果選擇了此項,則條件必須是一個表達(dá)式,該表達(dá)式計算為“true”。
Evaluate for all children
l勾選:對所有采樣器執(zhí)行前都判斷一次 l不勾選:僅入口判斷一次注意事項:在if邏輯控制器的Expression中不能直接填寫條件表達(dá)式,需要借助函數(shù)將條件表達(dá)式計算為true/false,可以借助的函數(shù)有__jexl3和__groovy函數(shù)
如果是字符串的比較,需要加””
"${url}"=="baidu"
表達(dá)式支持:
l==? 是否等于,如${__jexl3(${VAR}==1,)},判斷${VAR}變量是否等于1 l!= 不等于,如${__jexl3(${VAR}!=1,)},判斷${VAR}變量是否不等于1 l! 非,如${__jexl3(!(${VAR}!=1),)}對${VAR}!=1的結(jié)果取反 l&&或|| 且與或,如? ${__jexl3(${VAR}==1 && ${name} != "heima",)} l> 或者>==? ?大于等于,如${__jexl3(${count}>=10,)}循環(huán)控制器
目的:循環(huán)該控制器下面字節(jié)點的次數(shù)。
線程組里循環(huán)次數(shù)設(shè)置了n次,循環(huán)控制器下的循環(huán)次數(shù)也設(shè)置了m次,則該控制器下的請求運行的次數(shù)是(n*m)次。
分布式壓測介紹
?? ??? ?
?? ??? ? 普通壓測:單臺機可以對目標(biāo)機器產(chǎn)生的壓力比較小,受限因素包括CPU,網(wǎng)絡(luò),IO等
?? ??? ? 分布式壓測:利用多臺機器向目標(biāo)機器產(chǎn)生壓力,模擬幾萬用戶并發(fā)訪問
分布式壓測原理
?? ??? ?1、總控機器的節(jié)點master,其他產(chǎn)生壓力的機器叫“肉雞” server
?? ??? ?2、master會把壓測腳本發(fā)送到 server上面
? ? ? ? 3、執(zhí)行的時候,server上只需要把jmeter-server打開就可以了,不用啟動jmeter
?? ??? ?4、結(jié)束后,server會把壓測數(shù)據(jù)回傳給master,然后master匯總輸出報告
?? ??? ?5、配置詳情
實戰(zhàn)下次再更
總結(jié)
以上是生活随笔為你收集整理的Jmeter-基础篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么Python中整型不会溢出
- 下一篇: redis——事件