系統(tǒng)性能壓力測試
一、壓力測試
??壓力測試是給軟件不斷加壓,強制其在極限的情況下運行,觀察它可以運行到何種程度,從而發(fā)現(xiàn)性能缺陷,是通過搭建與實際環(huán)境相似的測試環(huán)境,通過測試程序在同一時間內(nèi)或某一段時間內(nèi),向系統(tǒng)發(fā)送預期數(shù)量的交易請求、測試系統(tǒng)在不同壓力情況下的效率狀況,以及系統(tǒng)可以承受的壓力情況。然后做針對性的測試與分析,找到影響系統(tǒng)性能的瓶頸,評估系統(tǒng)在實際使用環(huán)境下的效率情況,評價系統(tǒng)性能以及判斷是否需要對應(yīng)用系統(tǒng)進行優(yōu)化處理或結(jié)構(gòu)調(diào)整。并對系統(tǒng)資源進行優(yōu)化。
??在壓力測試中我們會涉及到相關(guān)的一些性能指標:
- 響應(yīng)時間(Response Time:RT):從客服端發(fā)送請求開始到獲取到服務(wù)器的響應(yīng)結(jié)果的總的時間
- HPS(Hits Per Second):每秒點擊的次數(shù)
- TPS(Transaction Per Second):系統(tǒng)每秒處理的交易數(shù),也叫會話次數(shù)
- QPS(Query Per Second):系統(tǒng)每秒處理查詢的次數(shù)
??在互聯(lián)網(wǎng)企業(yè)中,如果一個業(yè)務(wù)有且僅有一個請求連接,那么TPS=QPS=HPS的,而在一般情況下用TPS來衡量整個業(yè)務(wù)流程,用QPS來衡量接口查詢的次數(shù),用HPS來衡量服務(wù)器單擊請求。
??我們在測試的時候就會通過這些指標(HPS,TPS,QPS)的數(shù)據(jù)來衡量系統(tǒng)的系統(tǒng),指標越高說明系統(tǒng)性能越好,在一般情況下,各個行業(yè)的指標范圍有著比較大的差異,下面簡單的列舉了下,僅供參考
- 金融行業(yè):1000TPS~50000TPS
- 保險行業(yè):100TPS~100000TPS
- 制造業(yè):10TPS~5000TPS
- 互聯(lián)網(wǎng)大型網(wǎng)站:10000TPS~1000000TPS
- 互聯(lián)網(wǎng)其他:1000TPS~50000TPS
??當然我們還會涉及到一些其他的名詞,如下:
名詞 | 說明 |
---|---|
最大響應(yīng)時間 | 用戶發(fā)出請求到系統(tǒng)做出響應(yīng)的最大時間 |
最少響應(yīng)時間 | 用戶發(fā)出請求到系統(tǒng)做出響應(yīng)的最少時間 |
90%響應(yīng)時間 | 指所有用戶的響應(yīng)時間進行排序,第90%的響應(yīng)時間 |
??當我們從外部來看,性能測試主要要關(guān)注這三個性能指標
指標 | 說明 |
---|---|
吞吐量 | 每秒鐘系統(tǒng)能夠處理的請求數(shù),任務(wù)數(shù) |
響應(yīng)時間 | 服務(wù)處理一個請求或一個任務(wù)的耗時 |
錯誤率 | 一批請求中結(jié)果出錯的請求所占的比例 |
二、JMeter
1.安裝JMeter
官網(wǎng)地址:https://jmeter.apache.org/download_jmeter.cgi 下載后解壓即可,然后進入到bin目錄下雙擊 JMeter.bat文件即可啟動
該工具支持中文
中文后的頁面
2.JMeter基本操作
2.1 添加線程組
??線程組的作用就是定義任務(wù)的相關(guān)屬性,比如每秒執(zhí)行多少線程,重復多少次該操作
2.2 取樣器
??在定義了線程組后,我們得繼續(xù)定義每個線程的操作行為,也就是創(chuàng)建對應(yīng)的取樣器,在取樣器中我們定義要訪問的服務(wù)的協(xié)議及地址信息。
??然后我們需要在取樣器中定義服務(wù)的信息
2.3 監(jiān)視器
??在取樣器中我們定義了要訪問的服務(wù)信息,然后我們就要考慮請求后我們需要獲取任務(wù)的相關(guān)的指標信息。這時就用到了監(jiān)視器。
對應(yīng)的結(jié)果數(shù)據(jù)有 查看結(jié)果樹 匯總報告 聚合報告 ,查看結(jié)果對應(yīng)的圖形 匯總圖 …
2.4 測試百度
??寫好了取樣器后,啟動測試。
啟動后我們就可以查詢測試的結(jié)果數(shù)據(jù)
2.5 測試商城首頁
啟動后查看對應(yīng)的結(jié)果
2.6 JMeter Address 占用的問題
搜索之后發(fā)現(xiàn)需要在regedit中添加注冊表項MaxUserPort,TcpTimedWaitDelay重啟一下就可以解決了。
解決方法:
打開注冊表:ctrl+r 輸入regedit
進入注冊表,路徑為:\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
新建DWORD值,(十進制)設(shè)置為30秒。名稱:TcpTimedWaitDe,值:30
新建DWORD值,(十進制)最大連接數(shù)65534。名稱:MaxUserPort,值:65534
修改完成后重啟生效
三、性能優(yōu)化
1.考慮影響服務(wù)性能的因素
數(shù)據(jù)庫、應(yīng)用程序,中間件(Tomcat,Nginx),網(wǎng)絡(luò)和操作系統(tǒng)等
我們還得考慮當前的服務(wù)屬于
- CPU密集型:計算比較影響性能—>添加CPU,加機器
- IO密集型:網(wǎng)絡(luò)IO,磁盤IO,數(shù)據(jù)庫讀寫IO,Redis讀寫IO --》緩存,加固態(tài)硬盤,添加網(wǎng)卡
2.JVM回顧
JVM的內(nèi)存結(jié)構(gòu)
JVM中對象的存儲和GC
3.jconsole和jvisualvm
??jconsole和jvisualvm是JDK自帶監(jiān)控工具??梢詭椭覀兏玫牟榭捶?wù)的相關(guān)監(jiān)控信息,jvisualvm功能會更加的強大些。
3.1 jconsole
找到對應(yīng)的進程
3.2 jvisualvm
因為是jdk6.0后自帶的,我們同樣的可以在cmd或者搜索框中找到
打開的主頁面
找到對應(yīng)的進程,雙擊進入
查看對應(yīng)的監(jiān)視信息
添加插件。如果插件不可用,那么需要更新
https://visualvm.github.io/pluginscenters.html 需要結(jié)合你的jdk的版本來選擇對應(yīng)的插件的版本
安裝好之后重啟jvisualvm即可
%
4. 中間件的性能
??以下是一個完整的請求鏈路
??然后我們來測試下相關(guān)的組件的性能
壓力測試內(nèi)容 | 壓力測試的線程數(shù) | 吞吐量/s | 90%響應(yīng)時間 | 99%響應(yīng)時間 |
---|---|---|---|---|
Nginx | 50 | 7,385 | 10 | 70 |
Gateway | 50 | 23,170 | 3 | 14 |
單獨測試服務(wù) | 50 | 23,160 | 3 | 7 |
Gateway+服務(wù) | 50 | 8,461 | 12 | 46 |
Nginx+Gateway | 50 | |||
Nginx+Gateway+服務(wù) | 50 | 2,816 | 27 | 42 |
一級菜單 | 50 | 1,321 | 48 | 74 |
三級分類壓測 | 50 | 12 | 4000 | 4000 |
首頁全量數(shù)據(jù) | 50 | 2 |
中間件越多,性能損失就越大,大多數(shù)的損失都是在數(shù)據(jù)的交互
簡單的優(yōu)化:
中間件:單個的效率都很高,串聯(lián)的中間件越多,影響越大,但是在業(yè)務(wù)面前其實就比較微弱
業(yè)務(wù):
- DB(MySQL,優(yōu)化)
- 模板頁面渲染
壓力測試內(nèi)容 | 壓力測試的線程數(shù) | 吞吐量/s | 90%響應(yīng)時間 | 99%響應(yīng)時間 |
---|---|---|---|---|
Nginx | 50 | 7,385 | 10 | 70 |
Gateway | 50 | 23,170 | 3 | 14 |
單獨測試服務(wù) | 50 | 23,160 | 3 | 7 |
Gateway+服務(wù) | 50 | 8,461 | 12 | 46 |
Nginx+Gateway | 50 | |||
Nginx+Gateway+服務(wù) | 50 | 2,816 | 27 | 42 |
一級菜單 | 50 | 1,321 | 48 | 74 |
三級分類壓測 | 50 | 12 | 4000 | 4000 |
首頁全量數(shù)據(jù)(DB-Themleaf) | 50 | 2 | ||
一級菜單(DB-索引) | 50 | 1900 | 40 | 70 |
三級分類壓測(索引) | 50 | 34 | 1599 | 1700 |
首頁全量數(shù)據(jù)(DB-Themleaf-放開緩存) | 50 | 30 | 。。。 | 。。。 |
5.Nginx實現(xiàn)動靜分離
??通過上面的壓力測試我們可以發(fā)現(xiàn)如果后端服務(wù)及處理動態(tài)請求又處理靜態(tài)請求那么他的吞吐量是非常有限的,這時我們可以把靜態(tài)資源存儲在Nginx中。
5.1 靜態(tài)資源存儲
??把服務(wù)中的靜態(tài)資源上傳到Nginx服務(wù)中,把靜態(tài)資源文件打成一個zip包,然后拖拽到Linux中,然后我們通過
unzip index.zip
來解壓縮
然后替換掉模板文件中的資源訪問路徑
5.2 Nginx配置
??然后我們在Nginx的配置文件中指定static開頭的請求的處理方式
??保存后重啟Nginx服務(wù),然后就可以訪問了
6.三級分類優(yōu)化
??我們在獲取三級分類的數(shù)據(jù)的時候,會頻繁的操作數(shù)據(jù)庫,我們可以對這段代碼來優(yōu)化
??在此處我們可以一次查詢出所有的分類數(shù)據(jù),然后每次從這個一份數(shù)據(jù)中獲取對應(yīng)的信息,達到減少數(shù)據(jù)庫操作的次數(shù)的目的,從而提升服務(wù)的性能。
/**
* 跟進父編號獲取對應(yīng)的子菜單信息
* @param list
* @param parentCid
* @return
*/
private List<CategoryEntity> queryByParenCid(List<CategoryEntity> list,Long parentCid){
List<CategoryEntity> collect = list.stream().filter(item -> {
return item.getParentCid().equals(parentCid);
}).collect(Collectors.toList());
return collect;
}
/**
* 查詢出所有的二級和三級分類的數(shù)據(jù)
* 并封裝為Map<String, Catalog2VO>對象
* @return
*/
@Override
public Map<String, List<Catalog2VO>> getCatelog2JSON() {
// 獲取所有的分類數(shù)據(jù)
List<CategoryEntity> list = baseMapper.selectList(new QueryWrapper<CategoryEntity>());
// 獲取所有的一級分類的數(shù)據(jù)
List<CategoryEntity> leve1Category = this.queryByParenCid(list,0l);
// 把一級分類的數(shù)據(jù)轉(zhuǎn)換為Map容器 key就是一級分類的編號, value就是一級分類對應(yīng)的二級分類的數(shù)據(jù)
Map<String, List<Catalog2VO>> map = leve1Category.stream().collect(Collectors.toMap(
key -> key.getCatId().toString()
, value -> {
// 根據(jù)一級分類的編號,查詢出對應(yīng)的二級分類的數(shù)據(jù)
List<CategoryEntity> l2Catalogs = this.queryByParenCid(list,value.getCatId());
List<Catalog2VO> Catalog2VOs =null;
if(l2Catalogs != null){
Catalog2VOs = l2Catalogs.stream().map(l2 -> {
// 需要把查詢出來的二級分類的數(shù)據(jù)填充到對應(yīng)的Catelog2VO中
Catalog2VO catalog2VO = new Catalog2VO(l2.getParentCid().toString(), null, l2.getCatId().toString(), l2.getName());
// 根據(jù)二級分類的數(shù)據(jù)找到對應(yīng)的三級分類的信息
List<CategoryEntity> l3Catelogs = this.queryByParenCid(list,l2.getCatId());
if(l3Catelogs != null){
// 獲取到的二級分類對應(yīng)的三級分類的數(shù)據(jù)
List<Catalog2VO.Catalog3VO> catalog3VOS = l3Catelogs.stream().map(l3 -> {
Catalog2VO.Catalog3VO catalog3VO = new Catalog2VO.Catalog3VO(l3.getParentCid().toString(), l3.getCatId().toString(), l3.getName());
return catalog3VO;
}).collect(Collectors.toList());
// 三級分類關(guān)聯(lián)二級分類
catalog2VO.setCatalog3List(catalog3VOS);
}
return catalog2VO;
}).collect(Collectors.toList());
}
return Catalog2VOs;
}
));
return map;
}
優(yōu)化后的壓測表現(xiàn)
壓力測試內(nèi)容 | 壓力測試的線程數(shù) | 吞吐量/s | 90%響應(yīng)時間 | 99%響應(yīng)時間 |
---|---|---|---|---|
Nginx | 50 | 7,385 | 10 | 70 |
Gateway | 50 | 23,170 | 3 | 14 |
單獨測試服務(wù) | 50 | 23,160 | 3 | 7 |
Gateway+服務(wù) | 50 | 8,461 | 12 | 46 |
Nginx+Gateway | 50 | |||
Nginx+Gateway+服務(wù) | 50 | 2,816 | 27 | 42 |
一級菜單 | 50 | 1,321 | 48 | 74 |
三級分類壓測 | 50 | 12 | 4000 | 4000 |
三級分類壓測(業(yè)務(wù)優(yōu)化后) | 50 | 448 | 113 | 227 |
文章來源:http://www.zghlxwxcb.cn/news/detail-457275.html
可以看到系統(tǒng)性能的提升還是非常明顯的。文章來源地址http://www.zghlxwxcb.cn/news/detail-457275.html
到了這里,關(guān)于系統(tǒng)性能壓力測試的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!