一個性能測試案例的執行成本遠高於功能測試,那麼如何設計性能測試場景,以最少的案例拿出可以說明問題的結論,是全部關注性能問題的工程師的重要目標,同時也是一門工匠的藝術。前端
本文根據社區線上交流活動內容,進行彙總、概括、濃縮,將50餘個方方面面的知識點在最短的篇幅中展示給你們。包括以下內容:算法
1.性能測試策略的設計sql
2.性能測試場景的設計數據庫
3.性能測試環境的設計小程序
4.性能測試工具的選取和設計後端
1、性能測試策略的設計服務器
(一)如何制定性能測試策略?
性能測試策略須要考慮如下方面網絡
一、業務測試範圍session
哪些測,哪些不測。好比什麼業務測、什麼操做系統版本、中間件版本測。併發
二、制定優先級規則
因爲測試場景、測試案例是沒辦法窮舉的,理論上測試是永遠不可能結束的。而且,性能測試自己又牽涉出容量測試、擴展性測試、高可用測試、壓力下的異常測試等等的測試延伸,所以在給定的時間條件下,必須制定性能測試的優先級規則,根據優先級規則劃定測試範圍。性能測試的進展受制於功能驗證的完成、環境準備的完成、相關工具的開發、性能問題的定位和調優等,當性能測試的計劃須要變動時,能夠按照優先級規則從新選擇測試範圍。
三、基本的測試方法
例如:
a)如何產生業務壓力
b)如何產生用戶併發
c)如何構造場景使應用系統的邏輯處理算法達到生產的計算量級
d)如何製造外圍環境對被測目標的響應
四、測試環境設計
設計測試環境的拓撲結構和資源配置,由於測試環境的拓撲、資源不必定和生產環境相同。
須要想清楚爲何這麼設計,也就是說在這樣的環境下(多是精簡的環境)能夠得出可信度高的性能測試結論。
五、概要測試計劃
六、依賴條件
七、風險
等等
其中前4條基本決定了項目的工做量。更直接的說,前2條決定了測試人員能夠晚上幾點回家。
(二)「測測看」是否是一個有效的測試方法?
性能測試的成本是很是高的,「測測看」每每浪費嚴重。性能測試必須對測試場景有提早的規劃,而這個規劃的前提是對被測系統、產品有充分的瞭解。業務上面那些交易吞吐量大,從技術上講哪些服務器、哪些模塊容易出現性能瓶頸,甚至對操做系統、中間件、應用軟件的參數都要提早規劃好。否則測了不少案例,發現參數不合理,測試結論徹底做廢。固然,有時咱們並不能很準確的設計每一個參數,但至少要有一個計劃,我對那個參數進行調參的測試,以期測出最優的性能表現。
然而,「測測看」有它的可取之處,由於真正的性能表現只有測試以後纔會知道,筆者比較傾向的一種方式是,「提早規劃場景,每一個場景跑完以後分析結果,而後決定下一場跑不跑、跑什麼、參數怎麼設」。
(三)如何模擬和感知關聯繫統的壓力?
1)如何模擬核心繫統的正常壓力
不肯定你問的是哪一方面,就個人理解先回答一部分
一個交易或者請求的鏈路能夠很長,那麼,能夠從這條鏈路中任意一個節點,採用某種壓力工具進行施加壓力。好比:
a)能夠模擬end user的頁面操做,用Loadrunner、JMeter等性能測試工具錄製用戶的頁面操做,採用併發用戶回放,模擬用戶。
b)能夠模擬應用服務器直接給數據庫服務器施加壓力,採用性能測試工具,創建與數據庫的鏈接,直接把批量的sql語句扔過去
c)能夠直接採用數據庫錄製回放,把生產上錄製的數據庫sql在測試環境的數據庫回放。
發起壓力的機器離核心系統越近,越容易控制
2)如何感知在測試系統接入後對核心系統的壓力影響
這個由監控來作。日常不測試的時候,核心系統有多少TPS,多少CPU佔用、內存佔用,多少任務數,多少網絡帶寬佔用、磁盤IO、業務響應時間是多少。測試的時候,這些指標增長了多少,這個感知工做由監控來作。
(四)去掉前端系統,直接壓測後端,和真實狀況有差別嗎?
若是模擬的逼真,是沒有任何差別的。那麼問題來了,什麼是模擬的不逼真?
舉例1)生產環境某系統每秒處理100個事務,你若是採用性能測試工具,1個用戶每秒發100個請求,能夠模擬出系統每秒處理100個事務。可是,假如生產環境中這100個事務是由100個用戶發起的,那麼此時就有些差別了。首先,網絡通道的鏈接數可能不同,用戶登陸次數可能不同,session的打開數量,數據庫鏈接數,數據庫啓動的服務進程數等等都有可能不同。
舉例2)生產環境中每分鐘處理60個業務,這60個業務是勻速達到的。而你若是在性能測試的時候,在第一秒鐘把60筆業務都發出去了,後面59秒閒着。那麼這個模擬也是很是不逼真的。
(五)一場性能測試跑多長時間合適?
不少人一跑性能場景就跑1個小時以上,其實跑多久徹底取決於系統特色。有些系統在大壓力面前,幾秒鐘就能夠調整到位,後面只要壓力穩定,它的資源利用率、響應時間都是穩定的;對於這種系統,我的認爲測10分鐘足以。結果取下來,把前面幾秒鐘、後面幾秒鐘去掉,就能夠採集數據了。
而對於數據庫業務較複雜的場景,可能頭10分鐘的性能表現和後10分鐘徹底不同。這種狀況下,測試多久、數據取哪一段、要不要先給系統預熱而後再正式測試都是要具體分析的。
(六)白天執行性能測試仍是晚上執行?
不少企業選擇在晚上作性能測試是由於環境只有1套,白天有大量的功能測試人員趴在上,環境被改來改去,根本執行不了性能測試。只有晚上才空出來給性能測試那幾我的用。
然而,拋開環境共用的因素,從結果準確性的角度,我仍是比較推薦在晚上測,由於,測試環境資源是公用的,即便性能和功能測試是分別的兩套環境,業務上互不影響,但底層資源是互相影響的(網絡資源、計算資源、存儲資源)。從實際經驗來講,晚上測出來的結果和白天的結果的確不太同樣。
再然而,我更推薦白天測。由於人是要睡覺的。有時候咱們設置了定時任務,讓測試晚上自動執行,但這樣就不能及時獲取性能結果並及時分析,不能及時調整下一場測試的內容。致使不少無效的測試。
2、性能測試場景的設計
(一)是性能測試模型?
性能測試模型大概來講就是把哪些交易放到一塊兒測試,各個交易的交易佔比是多少。性能測試模型是從生產業務模型轉化而來的,按照性能測試模型來設計測試場景,能夠保證測試模擬更貼近生產實際的交易場景。通常都有這些模型:像正常交易日業務模型、峯值交易日業務模型、特殊交易日業務模型等。
(二)銀行核心業務系統的測試場景須要考慮哪些?
銀行類的系統,主要考慮聯機交易和批量交易測試場景,聯機交易場景:已上線的業務系統,須要先調研生產最近一段時間業務量分佈狀況,找出在什麼時間點系統交易量出現峯值,而後在深刻分析峯值時間點有哪些交易,交易的佔比,峯值持續時間等,造成測試模型;未上線的系統,在沒有明確的性能指標的狀況或可參看的歷史數據狀況下,可作探索性測試,找出系統在什麼時間、什麼地點出現拐點和瓶頸,而後進行分析和調優。批量交易場景:主要考慮批次時間窗口要求,同時還要關注批次疊加聯機交易的性能狀況。
(三)測試用例如何設計比較合適?
對於性能測試來講,主要是
1)測到點子上,即把最有可能出現瓶頸的地方測出來
2)在1)的前提下,儘可能少側
縮小測試範圍(只測某些業務、只測某個操做系統版本、只測某個中間件版本)。
同一個場景下,減小案例個數。負載測試,能測3場 就不測5場。
減小測試環境準備的成本,集中精力測試核心系統,或者由瓶頸的系統。其餘系統都扔開。
(四)基準->單交易負載->混合負載的弊端
教科書式的方法、八股文式的思路,不能適應具體的測試,由於或許不少的測試場景是在浪費時間。筆者更傾向於根據系統的業務特色、技術特色選擇少數幾個性能案例執行。
好比說,一共有10個交易,但生產環境98%的交易都是A,那麼單交易負載只測試A,混合負載甚至能夠不測。
再好比說,10個交易中,僅有交易B對數據庫的增刪改查壓力較大,而其餘交易交易沒有過重的數據庫訪問,那麼只測交易B。
(五)新建系統沒有任何過往數據的狀況下如何創建性能測試模型?
因爲新業務項目可能沒有明確的需求,也沒有生產上的歷史數據或者相似項目數據能夠分析。新業務的性能測試可採用探索性測試。探索性測試的目的在於給出該系統的整體性能表現、系統將在什麼時候何處出現性能瓶頸、並分析、定位問題,給出調優建議。
簡單來講,我不知道生產峯值TPS是多少,但我要知道本身系統在某個條件下的最大承載能力是多少,而且要分析出瓶頸在哪裏,若是要擴容知道怎麼擴。
對於不一樣的測試對象(測試功能點或測試模塊),需分爲不一樣的維度進行測試,並說明選擇這個分析維度的緣由。測試的維度須要按照測試的優先級排列。測試維度舉例:交易量的變化、用戶併發數的變化、交易配比的變化、數據文件大小的變化、軟件參數配置的變化、硬件參數配置的變化、存量數據的變化等等。每一類維度測試完成後,需選出最典型的值,在此基礎上進行下一維度測試。這麼作的目的是爲了減小測試分支。
舉例說明:
某系統中,某個模塊的併發查詢是性能關注點,可依據對查詢影響較大的幾個因素按優先級進行排序:不一樣的查詢條件,不一樣的併發用戶數、不一樣的存量數據。
一、不一樣的查詢條件,開發程序內部的處理不一樣,性能表現也不一樣,做爲第一個測試維度,需儘量分析程序內在實現方式,劃定測試範圍,測試後挑選更加典型的查詢條件,爲後續測試儘可能縮小查詢條件的範圍。
二、在維度一選定的典型查詢條件基礎上,選取不一樣的併發數進行測試。涵蓋需求中要求的併發數。驗證併發數是否知足需求,預測併發數多大時會達到性能瓶頸。並選擇合適的併發數做爲後續測試的併發參數。
三、在維度1、維度二選定的參數基礎上,進行不一樣存量數據的比對。
(六)設計哪些異常的測試場景?
性能場景設計中,異常場景主要有:
1)系統的異常:在業務壓力的狀況下進行高可用切換(好比一個進程掛了、一臺服務器掛了、一個站點掛了、一個光纖卡掛了、一臺存儲掛了),存儲空間滿了等等。
2)用戶犯的錯誤:選取生產系統容易發生錯誤的業務,這類業務因爲是錯誤的,因此應用的處理路徑、消耗的資源 和正常狀況下是不同的。
(七)二八原則在不少狀況下不適用
我目前接觸的生產環境,沒見過二八現象。由於如今的交易已經不太分時間段了,白天晚上都有很多交易。以銀行的業務A爲例,若是一天開門8小時,其中峯值的小時吞吐量 乘以5能夠獲得全天業務量。以銀行的業務B爲例,若是一天開門24小時,其中峯值的小時吞吐量 乘以10能夠獲得全天業務量。
(八)如何計算性能場景裏面的vu、Pacing
1)首先要指定TPS的目標
好比說我們打算髮到被測服務器的TPS=100,即每秒要100個請求。
2)根據TPS計算用戶數和間隔。
若是設置10個虛擬用戶,那麼每一個用戶每秒發10個請求。 那麼每一個用戶每隔100ms要發出來一個請求(1000ms/10=100)。
這100ms包含了2個時間(1)發送請求的時間,(2)停頓時間,即上一次發送結束到這一次發送開始,中間的停頓。
3)實測調整
若是「發送請求的時間」 自己就要90ms(這個是須要實測出來的),那麼你的停頓時間 應該是10ms,但10ms計算機是不可能穩定控制的,由於進程調度、CPU調度的緣由。最後致使發出來的TPS並不穩定。所以第一次測試,可能設置的不合理,不要緊,根據實測值,第二次測試就能夠設置合理了。咱們接着計算
由於剛纔的停頓時間10ms過短,我們至少要有30ms的停頓時間。那麼一個請求總體時間就是90+30=120ms。
這個狀況下,一個vu(虛擬用戶)一秒鐘能夠發出來多少筆請求呢?
1000ms/120ms= 8.33筆。那麼你要一秒發出來100個請求,須要多少vu呢?100/8.33=12個vu。 一臺壓力機放12個vu能不能跑出來想要的結果呢? 也不必定,由於這12個vu可能把壓力機給壓垮了。若是一臺壓力機不夠,能夠多加幾個壓力,共同跑12個vu。
3、性能測試環境的設計
(一)測試環境有限的狀況下測出接近生產的性能表現
企業裏的測試環境大部分都不如生產環境。在測試環境有限的狀況下,有什麼好的策略能夠在有限資源下測出接近生產的性能表現?
1) 將集羣環境改成單臺服務器,將有限的資源集中供應某一臺服務器。
這樣,能夠測試單臺設備的最大吞吐量。若是集羣環境中各個服務器之間沒有資源共享、資源徵用的話,單臺設備的最大吞吐量 * 設備數量 就是整個系統可以達到的最大吞吐量。固然,現實中沒有這麼理想,每每存在網絡共用、存儲共用,這就要深刻分析這些共享因素對性能的影響了。甚至有些集羣還有鎖機制,好比Oracle RAC,IBM CF,這些有鎖機制的集羣不太適合單臺的測試。
2) 去掉中間環節的服務器,直接壓測核心系統。
例如,一個客戶請求過來以後,通過F五、Web服務器、應用服務器、數據庫這幾個系統,而根據經驗判斷,前面幾個系統都不是性能瓶頸。那麼,能夠把前面的系統摘掉,採用性能測試工具直接壓測數據庫服務器。
再好比,業務系統的簽名經過簽名服務器來完成,但咱們想知道簽名服務器的最大吞吐量,那麼,去掉業務系統,直接壓測簽名服務器。
(二)在生產環境下作性能測試是否可行?
不少互聯網公司和部分中小銀行是採用生產環境作性能測試的,或是是共享了部分生產環境(例如網絡、存儲)作性能測試。
他們的特色是,「沒有辦法只能選擇生產環境作性能測試,而且出了問題也壓力不大」。
互聯網應用因爲系統龐大,沒有那麼大的測試環境來使用,而且,出了問題又能怎樣,反正是半夜測試的,一共也沒幾個用戶受影響,受影響又有什麼了不得,反正用戶是免費用的,過一下子就行了,對不住啦。
一些中小銀行也存在測試環境不足、出了問題也沒幾我的受影響的狀況。
因此,在生產環境下作性能測試對於一些企業是可行的,但對於另外一些則不行。好比,人民銀行的測試,總不能真刀真槍的測吧,出了問題,全部銀行業金融機構都受影響。銀行系統出了故障和互聯網公司的故障,民衆的容忍度是不同的。
(三)老舊的測試環境如何測試出合理的結果
這個問題實際上是兩個問題
1)設備型號和生產一致,但資源配置少
2)設備老舊
我們分別來看
1)設備型號和生產一致,但資源配置少
1.1) 將集羣環境改成單臺服務器,將有限的資源集中供應某一臺服務器
1.2) 去掉中間環節的服務器,直接壓測核心系統,或者直接壓測你認爲是瓶頸的系統。
2)設備老舊
設備也分爲好多類型,他們採用的技術、協議也不必定相同。咱們假設技術、協議是差很少的,只是型號老。
對於CPU資源)能夠對比測試設備和生產設備的TPCC/tpmC的值,有興趣能夠翻看個人文章http://www.aixchina.net/Artic...
對於內存資源)速度上新老設備是有差別,但每每影響不到太大的量級
對於存儲資源)若是能力相差很大,這個沒什麼好辦法。或者能夠把內存當作磁盤,ramdisk。把存儲的影響降到最低。
(四)局域網內如何模擬廣域網環境?
如何在測試環境模擬互聯網公網環境,或者模擬有帶寬限制(如100M/s)?
有一種設備叫網絡損傷儀,用來模擬帶寬大小,延時是多少毫秒,丟包率等等。
不過網絡損傷儀也不是模擬的特別好,有時候網絡損傷儀變成了網絡瓶頸,並無想象中那麼完美。
(五)用內網仍是外網測呢?
問:測試環境是用內網仍是外網呢?若是用內網,到時候若是是服務器端網絡帶寬問題是否沒法發現,用外網測試的話若是是壓力機網絡帶寬問題豈不是又要加帶寬?
答:若是貴司的業務是對外提供服務的,外網測比較真實,不只僅是網絡帶寬問題是否能被發現,還能夠發現由於網絡延時致使的一些問題。
帶寬佔用這個事,實際上是能夠算出來的,小壓力的跑一會,用TPS和服務器的網絡帶寬佔用 就能夠推算出來當生產壓力達到XX時,對應的服務器帶寬佔用。
廣域網網絡延時(好比30ms),若是你的交易要好多個來回交互,可能就會出現性能問題,有些代碼是有超時機制,超時就報錯了。
固然,若是單位的外網帶寬固定,也不是說加就加,那就在局域網測吧。但若是單位有錢,能夠買個網絡損傷儀,模擬廣域網的帶寬延時。
(六)虛擬化環境中得出的測試結論是否可信?
只要虛擬化的參數設置得當,測試結論是可信的。
好比說生產環境這個系統是10個CPU,那麼虛擬化環境也給足10個CPU便可
好比:設置dedicated CPU,或者EC=VP=10。
固然,還有網絡、磁盤、內存等其餘資源也一樣要設置得當。
(七)虛擬化資源和物理資源有沒有對應關係?
內存通常都是物理的,實實在在的。也有的hypervisor把磁盤給OS,讓OS誤覺得是內存,但通常沒這麼搞的。
CPU的話你要看你是什麼虛擬化平臺了,但均可以設置最低保障(標稱計算能力)
1)x86的CPU 能夠設置保障的Hz值。x86平臺在虛擬CPU的分配和控制上的確不是很精細。
2)Power的CPU,能夠設置EC(entitled capacity),一個EC約等於一個core。但此時VP的值要設置合理(若是過大,也會和實際狀況誤差很大),能夠設置EC=VP 這樣就和實際狀況很接近了。
或者,若是你對CPU機制瞭解比較多的話,也能夠去計算。任何虛擬化平臺的VP 都是一個線程,一個線程最多佔用一個邏輯CPU(也就是一個CPU超線程,或者一個CPU SMT)。你能夠把虛擬機CPU跑的很飽和,這時,你就能算出來,佔了多少邏輯CPU,再根據CPU型號,推算佔了多少個CPU core.
4、性能測試工具的選取和設計
(一)有哪些好的性能測試工具可用?
1) 測試工具經常使用的有:
Loadrunner:需license,但很多人是試用性質。功能、易用性方便最優秀,是性能工具的標杆
2) JMeter:無license,免費,是免費工具裏面的標杆。易用性差一點。
3) 固然然還有不少其餘工具,各有特點。還有些是專門測磁盤IO、網絡IO的小程序。
(二)用於模擬系統讀寫負載的測試工具?
在作主機及存儲系統等綜合測試(含高可用、性能)時,常會碰到沒法一開始就帶應用測試,但又須要模擬真實應用的讀寫場景。有哪些比較簡單又實用的測試工具,用於模擬系統的讀寫及計算負載?
磁盤IO的壓測工具:
例如orion、iometer,dd命令、xdd、iorate,iozone,postmark
不一樣的工具支持的操做系統平臺有所差別,各具特點。
有的工具能夠模擬應用場景,好比orion是oracle出品,模擬Oracle數據庫IO負載(採用與Oracle相同的IO軟件棧)。即模擬oracle應用對文件或磁盤分區進行讀寫(可指定讀寫比例、io size,順序or隨機)這裏就須要提早知道本身的IO模型。若是不知道,能夠採用自動模式,讓orion自動的跑一遍,能夠得出不一樣進程的併發讀寫下,最高的IOPS、MBPS,以及對應的響應時間。
比對dd,僅僅是對文件進行讀寫,沒有模擬應用、業務、場景的效果。
postmark能夠實現文件讀寫、建立、刪除這樣的操做。適合小文件應用場景的測試。
(三)性能指標採集工具
因爲性能指標包含不少方面
1)系統資源的指標(CPU、內存、網絡IO、磁盤IO)
2)服務指標(響應時間、吞吐量)
3)業務指標(業務量、併發用戶數、業務類型)
所以沒有一個現成的工具能夠抓取全部指標,緣由是,一些指標是和業務、應用關聯,須要用戶本身定製。好比某個業務的響應時間,須要從日誌採集,那就須要本身定製日誌採集和統計的工具。
固然,這些工具也能夠集成在一塊兒
N臺壓力機沒有跑出來N倍的效果
1)檢查你發送壓力的代碼,有沒有lock。具體來講,舉個例子,全部的交易要有全局惟一的交易編號。若是全部的壓力機上的交易標號是由一臺機器產生的,這臺機器產生編號的速度就是整個壓力機集羣的瓶頸。
2)檢查是否有資源共用。好比全部壓力機都是虛擬機,共用存儲、CPU等等。好比全部壓力機去某個數據庫讀數據。這個能夠看壓力機的資源利用狀況、響應時間就能夠看出來
3)多是被測系統已經到瓶頸了,壓力機能力再強,請求也發不出去了。