jmeter分佈式壓力測試

一。 壓力測試簡介css

     軟件測試(英語:software testing),描述一種用來促進鑑定軟件的正確性、完整性、安全性和質量的過程。換句話說,軟件測試是一種實際輸出與預期輸出間的審覈或者比較過程。軟件測試的經典定義是:在規定的條件下對程序進行操做,以發現程序錯誤,衡量軟件質量,並對其是否能知足設計要求進行評估的過程。
html

      性能測試是經過自動化的測試工具模擬多種正常、峯值以及異常負載條件來對系統的各項性能指標進行測試。負載測試和壓力測試都屬於性能測試,二者能夠結合進行。經過負載測試,肯定在各類工做負載下系統的性能,目標是測試當負載逐漸增長時,系統各項性能指標的變化狀況。壓力測試是經過肯定一個系統的瓶頸或者不能接受的性能點,來得到系統能提供的最大服務級別的測試。java

  •  負載測試:模擬實際軟件系統所承受的負載條件的系統負荷,經過不斷加載(如逐漸增長模擬用戶的數量)或其它加載方式來觀察不一樣負載下系統的響應時間和數據吞吐量、系統佔用的資源(如CPU、內存)等,以檢驗系統的行爲和特性,以發現系統可能存在的性能瓶頸、內存泄漏、不能實時同步等問題。負載測試更多地體現了一種方法或一種技術。
  •  壓力測試:在強負載(大數據量、大量併發用戶等)下的測試,查看應用系統在峯值使用狀況下操做行爲,從而有效地發現系統的某項功能隱患、系統是否具備良好的容錯能力和可恢復能力。壓力測試分爲高負載下的長時間(如24小時以上)的穩定性壓力測試和極限負載狀況下致使系統崩潰的破壞性壓力測試。

性能測試指標node

  •  RPS(Request Per Second):每秒處理請求數(處理開始處處理結束 中間時間成爲響應時間) 能夠經過測試工具 模擬多線程訪問某個http計算 jmeter中是經過聚合報告的throughput(吞吐量)查看 不一樣的系統因爲cpu 內存 磁盤 網絡的限制 rps(吞吐量重要指標)也就不一樣 
  •  QPS/TPS(Query/Transcation Per Second) :每秒查詢或者事務數 每一個請求多是基於查詢或者修改目的 請求被分爲查詢請求和事務請求 通常互聯網系統QPS>TPS  能夠說RPS是QPS和TPS的總和
  •  PV/UV:網站流量是指網站的訪問量,用來描述訪問網站的用戶數量以及用戶所瀏覽的網頁數量等指標,經常使用的統計指標包括網站的獨立用戶數量、總用戶數量(含重複訪問者)、網頁瀏覽數量、每一個用戶的頁面瀏覽數量、用戶在網站的平均停留時間等。網站訪問量的經常使用衡量標準:獨立訪客(UV) 和 綜合瀏覽量(PV),通常以日爲單位來衡量和計算。
         
    獨立訪客(UV):指必定時間範圍內相同訪客屢次訪問網站,只計算爲1個獨立訪客。
         綜合瀏覽量(PV):指必定時間範圍內頁面瀏覽量或點擊量,用戶每次刷新即被計算一次。
  •  併發量:就是同一時刻服務器在同時處理多少個請求  QPS=(同一時刻處理的請求 也就是併發量)/響應的時間,一個系統吞吐量一般由QPS(TPS)、併發數兩個因素決定,每套系統這兩個值都有一個相對極限值,在應用場景訪問壓力下,只要某一項達到系統最高值,系統的吞吐量就上不去了,若是壓力繼續增大,系統的吞吐量反而會降低,緣由是系統超負荷工做,上下文切換、內存等等其它消耗致使系統性能降低。

性能指標推算web資源公式
mysql

  假設目前需求肯定系統的平均日PV(多天pv總和/天數) 經過日PV能夠推算:
linux

  •  網絡帶寬=平均日pv/24*60*60*頁面的平均大小*(峯值和平均流量倍數 通常是5)
        假設平均日pv 100w   100w/(24-8)*60*60 【一天的總描述 除掉睡覺8個小時】 等於1s的pv =18
    峯值流程多是平均流程 5倍   秒pv(rps/qps/tps)=18 *5 =90  最後乘 平均每一個頁面大小 假設是 50KB
    最終帶寬 =90*50KB=5M帶寬

  •  併發數= PV / 統計時間 * 頁面衍生鏈接次數 * http響應時間 * 因數 / web服務器數量;  
       假設平均日pv 100w  100w、的秒pv(rps/qps/tps)  100w/(24-8)*60*60*峯值倍數5 =18 *5 =90
    qps*平均響應時間 假設2s =90*2=180  假設一個訪問派生的js /css /圖片是 10個 就是 180*10=1800併發數

  •  機器數=併發數/每 臺機器能處理併發數
       假設上面算出了日pv 100w須要1800併發數   單機能處理1000個併發 須要 1800/1000=2臺機器
  •  QPS=( 總PV數 ) / ( 天天秒數 【除掉8個小時睡覺時間】 ) = 每秒請求數(QPS)
  •  峯值QPS=( 總PV數 * 80% ) / ( 天天秒數 * 20% ) = 峯值時間每秒請求數(QPS)
         原理:天天80%的訪問集中在20%的時間裏,這20%時間叫作峯值時間
    100w 總pv  峯值qps= (100w*0.8)/(24*60*60*0.2)=80w/17,280=47qps
    使用qps計算機器:峯值時間每秒QPS / 單臺機器的QPS   = 須要的機器 

二。jmeter用法web

  1》jmeter安裝
spring

     下載jmeter4.0(http://jmeter.apache.org/download_jmeter.cgi) 前提安裝jdk1.8
  2》解壓並運行
        解壓後目錄結構以下
      sql

   printable_docs 用戶手冊和開始文檔 訪問index.html
   docs\api javaapi目錄 訪問index.html
   bin目錄 全部可執行文件目錄
  windows下點擊bin目錄下 jmeter.bat  linux下運行 jmeter.sh運行
  window下運行meter.bat會打開gui運行shell



打開界面風格

3》jmeter組件概念
  •    Test Plan也就是測試計劃,概念有點相似eclipse裏面的project(項目、工程)。 一個JMeter測試計劃有不少種測試元素組成。通常至少包含一個Thread Group(線程組),在每一個Thread Group裏面又能夠包含Controller,Listener,Timer等等。 
  • Thread Group就是線程組,,能夠看作一個虛擬用戶組,線程組中的每一個線程均可以理解爲一個虛擬用戶。線程組中包含的線程數量在測試執行過程當中是不會發生改變的。

  • JMeter主要有兩種類型的Controllers,Samplers和Logic Controllers。
      Samplers容許JMeter向server發送一系列的請求。她模擬了用戶從頁面想終端server發送請求的行爲,好比新建一個HTTP的Sampler,可執行POST、GET、DELETE等請求。
       Logic Controllers其實最主要的做用就是控制執行順序。她能夠用來控制sampler在一個線程中的執行順序,也能夠改變來自其餘elements請求的順序。典型的表明就是,IF Controller、While Controller等。 

    通常控制器都添加在線程組下 
  • Listeners 看到samplers測試執行的結果,形式多樣,包括表格、圖標、樹狀或者是日誌文件中的簡單文本。在每次smaplers執行的時候,結果數據都會被收集在多樣的Listeners中。 Listeners能夠加在test plan下的任何地方  
    好比 View Results Tree 能夠查看全部模擬線程的執行結果
           Summary Report/Aggregate Report 能夠查看吞吐量(qps)

  • Timers 默認狀況下,一個JMeter線程在sampler之間發送請求是不會暫停的。有時候這可能不是你想要的。這時候你就能夠加一個timer元素,你能夠用她來在每一個請求之間定義一個時間間隔。 

  • Assertions,有點相似JUNIT裏面的斷言,她能夠對請求中返回的結果作一些驗證性的處理。使用Assertions能夠定製請求正確時返回的成功信息,也能夠高亮返回的錯誤信息。 

      

  linux下shell下進行測試 能夠先使用window客戶端建立測試計劃  生成jmx文件拷貝到linux使用命令(http://jmeter.apache.org/usermanual/get-started.html#non_gui)

jmeter -n -t my_test.jmx -l log.jtl
生成的jtl  拷貝到window客戶端  打開Aggregate Report  能夠打開jtl文件表格預覽結果


4》jmeter簡單測試案例

 使用springboot開發幾個簡單的控制層案例 使用jmeter進行測試 使用jpa來操做數據庫
 maven依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>cn.et</groupId>
	<artifactId>springfox</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.8.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.24</version>
</dependency>
		
		<dependency>
    <groupId>io.springfox.ui</groupId>
    <artifactId>springfox-swagger-ui-rfc6570</artifactId>
    <version>1.0.0</version>
</dependency>
	</dependencies>
</project>
springboot配置文件application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
 控制層代碼
package test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@EnableAutoConfiguration
public class TestController {
	@Autowired
	private TestDao testDao;
	//普通輸出
	@RequestMapping(value="/pv",method=RequestMethod.GET)
	@ResponseBody
	String pv() {
		return "Hello World!";
	}
	//查詢數據庫
	@RequestMapping(value="/qps",method=RequestMethod.GET)
	@ResponseBody
	String qps() {
		Iterable<Shop> findAll = testDao.findAll();
		return "Hello World!"+findAll.iterator().next().getAddress();
	}
	//插入數據庫
	@RequestMapping(value="/tps",method=RequestMethod.GET)
	@ResponseBody
	String tps(Shop shop) {
		testDao.save(shop);
		return "1";
	}
	public static void main(String[] args) throws Exception {
		SpringApplication.run(TestController.class, args);
	}
}
java實體類

package test;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "shop")
public class Shop {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	@Column(nullable = false)
	private String name;
	@Column(nullable = true)
	private String address;
}

測試的dao

package test;

import org.springframework.data.repository.CrudRepository;

public interface TestDao extends CrudRepository<Shop, Integer>{	
}
數據庫
CREATE TABLE `shop` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(29) DEFAULT NULL,
  `address` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=latin1;

/*Data for the table `shop` */

insert  into `shop`(`id`,`name`,`address`) values (1,'9','aaaaa'),(2,'100','aaaaa'),(3,'94','aaaaa'),(4,'15','aaaaa'),(5,'114','aaaaa');

使用jmeter測試的地址爲 :

  http://localhost:8080/pv 直接測試輸出內容
  http://localhost:8080/qps 直接查詢數據庫
  http://localhost:8080/tps 直接測試操做數據庫數據

pv和qps都沒有參數傳遞 操做過程參考
在測試計劃 添加線程組
    Numbers of Users 設置爲 1000 表示同時啓動1000個線程併發

    Loop Count設置爲10 每一個線程會循環10次 

添加 sampler 的 Http Request 輸入ip和端口 請求的path 保存爲jmx文件 
添加listener  的 Summary Report 用於監聽併發量 


這裏測試結果查看Summary Report的Throughout(吞吐量qps)個人結果是
/pv  3000左右qps 

/qps  1500不到qps

tps有參數傳遞 操做過程參考

tps模擬三千個併發 每一個都到數據庫插入數據 必須是不同的數據  此時咱們能夠添加一個計數器 讓他自增

值的設置參考

在http request的頁面須要添加兩個參數 name和address


在添加一個listerner View Results Tree 能夠看實際執行被替換的值 點擊運行開始測試 (啓動springboot程序)
查看吞吐量  1000左右

查看實際運行參數

固然動態值可使用csv維護 或者隨機值 均可以


三。jmeter分佈式壓測
 
上面的測試是負載測試 沒有達到系統極限 只是爲了獲取單機的吞吐量

若是系統須要作壓力測試 必須測試出系統的極限 也就是出現錯誤率  可是單機的線程數有限 好比設置線程數 10000時系統就已經死機  沒法進行測試  能夠將10000個線程分發到多個系統中進行測試 而後將多機結果合併到一個客戶端進行統計 這就是分佈式壓測 原理圖以下

具體部署過程參考 http://jmeter.apache.org/usermanual/jmeter_distributed_testing_step_by_step.html

注意點:

  • You have setup SSL for RMI or disabled it.   文章中描述 必需要安裝sslforrmi或者禁用他

jmeter4.0後 默認遠程測試 必須使用ssl for rmi來進行資源分配 能夠禁用他 找到 bin/jmeter.properties(全部客戶控制機和

agent代理機)都須要修改

server.rmi.ssl.disable=true
若是不想禁用他 能夠在任意一臺機器生成keystore文件 參考http://jmeter.apache.org/usermanual/remote-test.html#setup_ssl

執行bin\create-rmi-keystore.sh  
輸入別名rmi 其餘的隨便輸入 密鑰對密碼直接回車默認密碼時changeit最後輸入yes 會在bin目錄下生成rmi_keystore.jks
若是按照上面規則生成的就不須要修改任何配置 拷貝到全部其餘機器的jmeter/bin目錄 若是別名不是rmi密碼也本身設置了
能夠修改 jmeter.properties文件 以下相關項

#
# Configuration of Secure RMI connection
#
# Type of keystore : JKS
#server.rmi.ssl.keystore.type=JKS
#
# Keystore file that contains private key
#server.rmi.ssl.keystore.file=rmi_keystore.jks
#
# Password of Keystore
#server.rmi.ssl.keystore.password=changeit
#
# Key alias
#server.rmi.ssl.keystore.alias=rmi
#
# Type of truststore : JKS
#server.rmi.ssl.truststore.type=JKS
#
# Keystore file that contains certificate
#server.rmi.ssl.truststore.file=rmi_keystore.jks
#
# Password of Trust store
#server.rmi.ssl.truststore.password=changeit
#
# Set this if you don't want to use SSL for RMI
#server.rmi.ssl.disable=false
修改windows客戶機agent的地址
remote_hosts=192.168.58.149,192.168.58.150

兩個agent機器上 分別啓動

./jmeter-server
出現如下表示成功
[root@node2 bin]# ./jmeter-server         
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.58.149:58159,SSLRMIServerSocketFactory(host=node2/192.168.58.149, keyStoreLocation=rmi_keystore.jks, type=JKS, trustStoreLocation=rmi_keystore.jks, type=JKS, alias=rmi),SSLRMIClientSocketFactory(keyStoreLocation=rmi_keystore.jks, type=JKS, trustStoreLocation=rmi_keystore.jks, type=JKS, alias=rmi)](local),objID:[3e87da73:162ad2d59e0:-7fff, -8236211744330230598]]]
window機器 點擊jmeter.bat啓動界面 添加測試計劃 點擊run - startall 就能夠啓動測試

在agent機器的linux命令行 能夠看到 輸出

Starting the test on host 192.168.58.149 @ Mon Apr 09 18:37:57 PDT 2018 (1523324277629)
Finished the test on host 192.168.58.149 @ Mon Apr 09 18:38:33 PDT 2018 (1523324313314)
表示 開始成功測試 檢測多個agent是否同時有輸出
相關文章
相關標籤/搜索