一。 壓力測試簡介css
軟件測試(英語:software testing),描述一種用來促進鑑定軟件的正確性、完整性、安全性和質量的過程。換句話說,軟件測試是一種實際輸出與預期輸出間的審覈或者比較過程。軟件測試的經典定義是:在規定的條件下對程序進行操做,以發現程序錯誤,衡量軟件質量,並對其是否能知足設計要求進行評估的過程。
html
性能測試是經過自動化的測試工具模擬多種正常、峯值以及異常負載條件來對系統的各項性能指標進行測試。負載測試和壓力測試都屬於性能測試,二者能夠結合進行。經過負載測試,肯定在各類工做負載下系統的性能,目標是測試當負載逐漸增長時,系統各項性能指標的變化狀況。壓力測試是經過肯定一個系統的瓶頸或者不能接受的性能點,來得到系統能提供的最大服務級別的測試。java
性能測試指標node
性能指標推算web資源公式
mysql
假設目前需求肯定系統的平均日PV(多天pv總和/天數) 經過日PV能夠推算:
linux
二。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
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個線程分發到多個系統中進行測試 而後將多機結果合併到一個客戶端進行統計 這就是分佈式壓測 原理圖以下
注意點:
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是否同時有輸出