效能測試場景設計深度解析
感謝合眾支付資深技術專家程超的推薦與審校。
作者:張允慶,現就職於易寶支付有限公司,任職高階效能測試工程師,有多年的系統性能測試設計與優化經驗,經歷過大小上百個專案的效能優化,對效能測試有著較為深入的研究。2008年底獲得北京大學理學學士學位,目前進入對外經濟貿易大學在職研究生班進行深造,專業方向是大資料分析及應用。對效能測試相關話題感興趣的讀者可以和作者進行交流,電子郵箱地址:[email protected]。
責編:陳秋歌,尋求報道或者投稿請發郵件至chenqg#csdn.net,或加微信:Rachel_qg。
瞭解更多前沿技術資訊,獲取深度技術文章推薦,請關注CSDN研發頻道微博。
說在前面
提到效能測試,大家想到的就是使用工具對應用進行加壓,看看應用能承受多少併發,TPS(Transactions Per Second)是多少,交易響應時間是否在接收的範圍內。不錯,這些都是大家最關心的應用的效能指標,也是每個效能測試專案輸出的結果。然而,要實現這樣的效果卻並不是一件簡單的事情,因為效能測試是一個十分複雜的系統工程,對測試人員的能力水平提出了更高的要求,需要效能測試人員具備非常全面的知識與技能,能夠定位應用的效能瓶頸,並提出適當的優化方案。
通常,要對一個應用進行效能測試需要經歷需求調研、環境準備、指令碼開發、資料預埋、場景設計、場景執行、應用監控分析、瓶頸定位、瓶頸修復、迴歸測試、結果整理、輸出報告等多個環節。
今天我們先談一談效能測試中的場景設計。
效能測試的場景設計
效能測試的場景如何定義?我們可以理解為功能測試中的用例,即效能測試的場景就是效能測試的用例。效能測試的場景是為了要實現特定的測試目標而對應用執行的壓測活動。效能測試場景的設計與執行是整個效能測試活動的核心與靈魂,沒有完整的場景設計就無法達到我們的測試目的,沒有合理的場景設計就不會發現系統的效能缺陷。我們所開發的測試指令碼,所預埋的測試資料都是為了實現特定場景所準備的。
一個性能測試場景包含諸多要素,圖1中列出了一些必備的要素,其中測試模型作為測試場景的基礎與輸入。
圖1 效能測試場景的組成要素
下面對每一個要素做一個簡單的說明。
測試模型與測試指標
在進行場景設計之前我們應該先確定了本次效能測試的測試指標與測試模型。測試指標和測試模型是進行場景設計的前提和基礎,是場景的輸入。根據被測系統的型別不同,可能測試指標的型別略有不同。對於線上Web類的應用,測試指標一般包括線上使用者數、最優併發使用者數、最大併發使用者數、交易平均響應時間、目標TPS等等。對於介面呼叫類的應用測試指標一般包括目標TPS、平均響應時間等。
測試模型就是被測試系統的各交易線上執行時承受的交易數量(或請求數量)的比例而不是併發使用者的比例。為什麼不是併發使用者的比例呢?因為實際的使用者的操作具有不確定性,使用測試工具很難模擬真實使用者的行為。另外,在進行運營資料分析時很難獲取使用者的操作行為,而應用的交易記錄卻很容易通過查詢的方式獲取。應用實際承受的壓力是使用者的實際操作請求,線上使用者如果沒有進行實際操作那麼他最多將消耗一個連線執行緒,而應用CPU並不會有什麼資源消耗。100個使用者平均每個花費10秒下一個訂單和10個使用者每1秒鐘下一個訂單對應用帶來的壓力是一樣的。所以,在場景中能用最少的併發使用者來模擬真實的請求是最經濟的選擇方式。
那麼,測試模型到底該如何確定呢?通過需求調研獲得。下面介紹的兩點是我們常用的調研方式:
- 對於還未上線運營的新系統,我們一般會讓應用的產品經理或負責人給出一個預估的比例;但是這個預估需要我們進行評估,不是隨意的。對於一個以提供下單交易為主的應用,通常下單交易是佔整個模型的較大比例,如果需求方提出的模型是查詢比例較高,那麼我們就有理由懷疑該模型的合理性。對於這種情況,我們建議選擇幾個常見的典型的模型來配合需求模型進行場景設計。
- 對於已上線運營的應用,我們一般會分析實際的交易資料來確定交易比例,這樣會更加精準。例如一個應用對使用者提供下單、查詢、退款三個交易,我們通過DBA線上查詢某日的交易資料總量為200000筆,其中交易下單160000筆、查詢38000筆,退款2000筆,由此我們算出各交易的比例是80%、19%、1%,那麼這個比例就是我們的測試模型。
被測交易或使用的指令碼
測試指令碼是測試場景的基礎,指令碼包括對應的測試資料,例如登入所需要的使用者名稱與密碼、下單交易可能需要的銀行卡號等等。考慮到效能測試是多使用者併發的測試,所以需要提前準備相應的測試資料,例如一個場景要對一個含登入操作的交易進行壓測,那麼我們在場景設計時就要考慮可用的使用者名稱與密碼數量;又如,要對退款交易做測試,那麼就需要提前準備好可以退款的資料,這就需要提前做好資料預埋準備。
一般情況下,為了方便我們統計TPS,建議一個指令碼只包含一個完整的交易,不要把多個交易放到一個指令碼中。因為,不同的交易其響應時間會不同,響應時間較長的交易會成為“瓶頸”。另外,我們設計測試場景時需要考慮不同交易的佔比,如果多個交易存在同一個腳本里,場景的設計就無法實現。
上文提到的“被測交易”是我們壓測的物件,也是應用的入口。當然,並不是被測應用的每個交易都需要進行壓測,這要視具體情況而定。如果被測應用提供的交易非常多,我們可以考慮只選取佔比比較大的交易進行壓測,而佔比較低的交易可以忽略。
併發使用者數量或併發執行緒數量
併發使用者和併發執行緒其實是同一個概念,只是在不同的效能測試工具中其叫法不同而已。在下文中我們統稱“併發使用者”。當然,這些使用者是虛擬使用者,是壓力測試工具使用程序或執行緒來模擬真實使用者請求的一種方式。併發使用者是每個場景提供不同壓力的直接來源,場景不同其需要的併發使用者數量可能會不同。那麼是什麼因素決定一個場景要併發使用者的多少呢?主要是被測交易的響應時間和場景的目標TPS。交易響應時間的快慢是決定併發使用者數量的主要因素,例如一個應用的某個交易響應時間是50ms,如果要實現100TPS的目標,那麼只需5個併發使用者即可達到(目標TPS*交易平均響應時間=併發使用者量)。如果響應時間是100ms,那麼實現同樣的TPS需要的併發使用者就會多一倍。
加壓策略
加壓策略就是併發使用者以什麼樣的“步調”開始對應用發起請求。常用的併發策略有同時載入、指定間隔時間的載入,梯度載入等方式。加壓策略的不同主要是模擬生產環境不同的情況,下面分別做簡單介紹。
同時載入方式是指所有併發使用者在場景啟動時同時發起交易請求而不包含任何等待,這樣會對被測應用帶來突然的壓力,用於考察應用在突然加壓下的表現是否符合預期。一般有使用者突增的業務特點的應用會設計這樣的場景,例如,某些搶購系統、鐵路售票系統的按時放票功能等。當然,對於那些併發使用者較少的場景也可以採用這種使用者載入方式。而對於有些應用如果同時載入大量的併發使用者可能會出現異常或超時,導致部分併發使用者失敗。
指定間隔時間的載入方式是我們最常用的,這是為了模擬生產的實際情況,一般生產系統接收使用者請求都是逐漸增加的,到當日交易的高峰時段達到最大。在場景設計時,根據併發使用者的多少可以設定適當的增加頻率,一般是“多長時間增加多少使用者”。例如,每一秒鐘增加一個使用者、每兩秒增加5個使用者等等。
梯度加壓策略也是我們常用的一種使用者載入方式,但是這種方式嚴格來說應該是一種梯度加壓場景。該場景一般是預先設定幾個併發使用者的梯度,每個梯度執行幾分鐘,這樣就可以通過一個場景的執行基本上找到應用的最大TPS。在下文場景型別中,我們會詳細介紹這種場景。
執行時間
每個型別的場景其執行時間是不同的。表1為大家提供一個參考值。執行時間是不包含使用者的載入時間和退出時間的,即全部使用者都在執行的這段時間。
表1 各種典型場景執行時間設定
延時方式
延時是上一筆請求完成到下一筆請求發起之間的時間間隔。延時在場景中的作用就是為了精準控制TPS,或者降低當前併發使用者數量下的壓力。而精準控制TPS的目的就是考察應用在特定壓力下是否存在效能問題。在某些效能測試工具中提供了三種延時設定方式:
第一種是上一次請求完成後立即發起下一次請求,也就是延時為0。
第二種是上一次請求完成後間隔指定的時間後再發起下次請求。
第三種是在指定時間內完成一次請求,即區間型的延時,這要求我們設定的這個時間要大於交易的響應時間,也就是說要保證交易響應時間在我設定的這個時間的區間內,否則就不能實現精準控制TPS的目標。在這個區間內,交易響應時間無論如何變化,只要不突破我的這個最大區間,那麼TPS就是平穩的。
在實際的場景設定中,為了實現精準的TPS控制目標,我們選用第三種設定方式。通過不斷地嘗試與調整,最終能夠達到目標TPS。
使用者終止方式
和使用者載入方式對應,使用者終止方式是場景執行完成後的使用者退出方式。一般使用的是“同時退出”和“每隔多少時間退出幾個使用者”這種方式。這裡我們重點介紹一下“同時退出”這種方式。應用在持續一段時間的壓力後如果突然壓力全部釋放了,那麼這時的應用在理想情況下應該是怎樣的?CPU資源應該從繁忙立即變為空閒,網路傳輸也大幅降低,磁碟IO降為0等等。不然,那就是有某種問題的存在了。這時候就需要分析導致資源不能釋放的原因。
各種資源的監控方式
資源的監控方式也是我們場景設計時必須考慮的一個必要因素,在場景設計時就應該確定每個場景的資源監控策略。這些策略包括監控的物件、使用的監控工具或方法、監控資料採集頻率等。監控物件一般是測試環境中所有作業系統資源使用(CPU、記憶體、磁碟IO、網路吞吐等)、資料庫(TOP SQL、資料庫鎖等待與死鎖、緩衝區命中率等)、JVM的執行情況(堆記憶體垃圾回收、執行緒狀態、資料庫連線池使用情況等)等。監控資料採集頻率也會因場景執行的時間長度不同而進行適當調整,例如混合容量場景如果執行30分鐘,那麼採集頻率可以為每5秒鐘採集一次,共採集360次。但是,考慮到監控要提前啟動,所以採集次數可以適當增加一些,這樣可以確保整個監控區間大於場景執行區間,也就同時監控到了資源使用在壓力發起前後的變化情況。對於執行時間較長的場景,我們就要適當調整採集間隔和採集次數,例如對於一個執行12小時的穩定性場景,我們可以每50秒採集一次,共採集1000次。
常見的場景型別
單交易基準
一般使用一個使用者或一個執行緒,延時設定為0,對一個交易持續執行10分鐘以上。該場景的主要目的是獲取單個交易在無壓力的情況下的基準響應時間及環境資源使用情況,作為其他場景的參考依據。
單交易負載
單交易負載的場景是為了找到單個交易的最優TPS,檢測單交易在併發情況下是否存在效能瓶頸。這個最優是以什麼為衡量標準呢?通常以應用或資料庫等系統的CPU使用率不大於70%為標準。為什麼是70%?不能更高了嗎?通常在生產上執行的應用,如果CPU使用率長期處於高水平那是非常嚴重的問題,應用的節點隨時都可能掛掉。對於生產環境各種資源的使用情況,通常運維部門都會有實時的監控,一般當摸個節點的CPU使用率超過50%時就會觸發報警,如果長時間處於高負載狀態,那麼說明應用節點可用資源不足,就應該考慮進行節點擴充了。
當然,也並不是什麼情況下都需要找到單交易的最優TPS,這要分情況來對待。對於被測應用提供的交易比較少的話,可以通過不斷測試找到每個交易的最優TPS。但是,有的應用提供的交易比較多,這時如果每個交易的最優TPS都要找到,那就會需要較多的時間來進行測試。
單交易負載的場景具體該如何設計與執行呢?如果你想找出每個交易的最優TPS,可以從5個併發使用者開始,執行幾分鐘後再增加5個使用者,直到應用CPU使用率超過70%為止。場景的延時設定為0,場景執行前需開啟相關監控。該場景用於獲取單交易在併發情況下的響應時間與TPS,發現交易本身是否存在併發問題,應用是否會出現錯誤和異常,響應時間相對單交易基準是否有明顯的提高,資源使用率是否在合理的承受範圍之內等等。如果應用存在效能缺陷該場景即可發現。
當然,如果你不想測試出每個交易的最優TPS,那麼單獨對每個交易做一次5個併發的負載測試即可。
多交易混合負載
多交易混合負載的目的是為了找到應用的最優TPS,即應用CPU資源消耗在70%左右時的TPS(此時需確保資料庫等其他被呼叫資源不成為瓶頸)。
按照測試模型中的交易比例及目標TPS,對每個交易分配不同的併發使用者數量,設定不同的延時,同時進行加壓,通過多個子場景的不斷嘗試最終測試出應用能夠達到的最優TPS。這個場景比較複雜,一般需要經過多次的測試與調整才能到達測試模型的比例要求。經過單交易負載測試之後我們已經獲取了每個交易的平均響應時間,那麼由此值我們便可以設定我們的混合負載場景。假設,我們應用的測試指標TPS為100,單交易負載測試獲取的各交易響應時間如下:下單0.4秒,查詢0.2秒,退款0.5秒,那麼要達到100TPS的壓力,該如何設定場景?
計算每個交易的TPS
下單TPS=100*80%=80,查詢TPS=100*19%=19,退款TPS=100*1%=1確定每個交易的併發使用者
目標TPS、響應時間、併發使用者之間有這樣一個關係:
目標TPS=併發使用者/響應時間
如果一個交易響應時間是0.2秒,那一個使用者時的TPS就是1/0.2=5。
在咱們這個例項中每個交易的併發使用者計算如下:
下單交易併發使用者數量=80*0.4=32
查詢交易併發使用者數量=19*0.2=3.8
退款交易併發使用者數量=1*0.5=0.5
大家看到了,這裡出現了非整數的情況,怎麼辦?對於這種情況我們要進行整數化處理。即我們一般取大於並最接近當前數的整數,3.8我們按4,0.5我們按1。整數化後對應的響應時間也應該發生變化,否則就無法實現目標TPS。整數化再次計算實際的響應時間:
查詢交易調整後的響應時間=4/19=0.21
退款交易調整後的響應時間=1/1=1
於是場景設定如下,下單交易併發使用者32個延時設定為0秒,查詢交易併發使用者4個延時設定0.01秒,退款交易併發使用者1個延時設定0.5秒,場景執行時間10分鐘以上。但是這個場景執行結果可能並不會完全符合我們的預期,因為併發使用者相比單交易負載場景已經增加了很多,交易的響應時間很可能會出現明顯的延長。比如下單交易的實際響應時間可能會延長到0.6秒,那麼實際的TPS將明顯下降。如果出現這種情況該如何處理呢?我們推薦使用區間型延時設定,將這個“區間時間”設定的比實際交易響應時間大一些,根據這個時間再計算對應的併發使用者量。另外,建議大家建一個excel的表格,用於計算延時和併發使用者的值,效果見下表2。
表2 場景設定工具表
表2中的列“延時設定”的值是使用公式自動計算出來的,公式為“=併發使用者單元格編號/(目標TPS單元格編號*交易佔比單元格編號)”。建立這個表之後我們只需手動修改兩個列的值就可以方便地計算出每個場景下的每個交易的延時,這兩個列就是“平均響應時間”和“併發使用者數”。平均響應時間隨著併發使用者的增加必然會相應地增長,所以在表2中每個場景的平均響應時間資料都是上個場景的執行結果。這樣我們每執行完成一個場景,然後就把響應時間的資料填寫到下個場景中,然後再修改併發使用者數量,並確保延時設定大於平均響應時間即可,如果在測試執行過程中出現平均響應時間大於延時設定時間時需要停止場景重新計算。
綜上所述,多交易混合負載場景並不是一個場景,而是一系列混合場景的集合。還以上例來說,目標100TPS時我們分析監控結果發現系統各項資源利用率都不是太高,這說明應用還能夠承受更大的壓力。這就需要我們繼續加大壓力進行測試。我們可能的場景是150TPS、200TPS等等。那麼如何確定我們的壓力梯度呢?這就要看系統資源到底使用了多少,如果100TPS時發現系統各項資源使用率在50%左右,我們就可以估計應用的最優TPS應該能夠達到150,那麼我們下一個場景就是要按150TPS的目標壓力去發壓,相關的併發使用者和延時根據上表進行調整即可。如果不能實現150TPS的壓力,那麼我們就要減少目標TPS再進行發壓,直到測試獲取到應用的最優TPS。
多交易混合容量
容量的意思就是應用能夠達到的最大TPS。該場景是和多交易混合負載場景相關聯的,即通過多交易混合負載找出應用承受的最優TPS後繼續對應用進行加壓,直到找到應用的最大TPS。混合容量場景的併發使用者與延時調節方式和混合負載一樣,在這裡就不再贅述了。
大併發
該類場景的目的是考察系統在大併發的情況下是否存在問題,是否有報錯,是否有使用者失敗等。大併發一般要設定一個延時,用於到達最優併發時的TPS。那麼,大併發時的使用者到底設定多少,這個延時要設定多久,依據是什麼呢?一般我們設定的併發使用者數量是最優併發的5至10倍,而延時要通過計算得到。這裡還是舉例說明,有一個應用,測試得到的最大TPS為200,對應的併發使用者為20,那麼我們可以設定兩個大併發場景,即100併發使用者和200併發使用者。100併發時的延時設定為100/200TPS=0.5秒,200併發時的延時設定為200/200TPS=1秒,這個延時為區間型的延時。
通常,在進行大併發測試時獲得的TPS結果要比最大TPS低很多,因為在大併發時系統很有可能出現某些資源不夠用,執行緒很可能會出現嚴重的阻塞等等。
如何考量大併發測試獲得的測試結果是否符合預期,或者說大併發測試通過的標準是什麼?這個也沒有固定的標準可循,通常我們認為只要符合如下兩方面的要求即可認為測試通過。
最大併發使用者量是否能達到最大TPS時的5倍;
測試結果的TPS是否達到測試指標的要求;
需要說明的是這裡的大併發和應用的最優併發與最大併發並不是一回事,二者並不相同。
穩定性
給應用一個恆定的壓力,使場景執行較長的時間,用於測試應用在長時間執行下的表現,TPS是否有較大波動、是否有錯誤和異常、是否存在記憶體溢位等。根據業務型別不同一般會執行不同的時長,對於5*8這樣的應用穩定性執行8小時即可,7*24這樣的應用最好能夠執行12小時以上。
恆定的壓力怎麼選取?通常有兩種方式。第一種,選擇應用最優壓力的80%最為目標壓力,這種方式比較適合應用的最優TPS不是很高的應用,比如200以下;第二種,如果應用的TPS比較高,那麼我們需要換一種方式,否則就會產生較多的測試資料。例如一個應用的最優TPS為1000筆/秒,如果我們取其80%的壓力800筆/秒,那麼加壓12小時的資料量為3456萬!這時,我們使用200TPS的恆定壓力執行12小時即可。
擴充套件性
考察應用的擴充套件能力。未擴充套件的情況下基本是一個子系統使用一個單獨的機器節點,也就是應用的單點情況。擴充套件性就是,再對應用進行一個節點的擴充套件,測試擴充套件情況下的TPS。一般雙節點的總TPS達到單節點的1.8倍即認為系統具有良好的擴充套件性。壓測時我們選取混合容量場景中獲取到應用最大TPS時的場景做為壓測場景,並使用不同的壓力機分別對兩個節點進行加壓,考察測試結果能夠達到多少TPS。
可靠性或異常測試
這種情況下一般是將壓力做為背景,對應用所依賴的環境進行模擬故障,考察應用的表現是否符合預期。例如,在一定壓力背景下,模擬網路的閃斷,待網路恢復後應用TPS是否能夠及時恢復。背景壓力我們一般選取混合負載測試獲取最優TPS時的場景即可。
影響性
影響性測試也是效能測試過程中經常遇到一類場景。這種場景一般是針對提供非實時功能的應用所設計的。例如,有批處理或非同步處理的應用。嚴格來說,這不應該算是一個單獨場景型別,應該是一種特定的測試型別。對於這類的測試我們一般分兩步來執行,首先是在未啟用具有影響性的功能時測試出應用的最優和最大TPS;其次,啟動具有影響性的功能,再按第一步的場景(場景的設定均不變)進行測試,對比二者的TPS差別,這個差別就是我們要考察的影響性。
擋板延時對比
如果壓測環境使用了擋板,可以通過擋板來設定不同的延時進行對比測試。比如延時設定為0.5秒,1秒,甚至2秒。根據不同的延時設定,增加相應的併發使用者數量,調整場景的各項設定,考察應用是否能夠達到最大TPS,是否出現併發使用者失敗或應用異常等。對於擋板延時,一般的作用是模擬被呼叫的系統的延遲,考察被測應用在不同的延時情況下的效能表現。現在的應用系統很少有是完全獨立的了,或多或少地都需要呼叫別的系統來實現某些操作或業務。例如,對於一個支付系統,起碼需要呼叫銀行通道、銀聯通道、手機簡訊通道等等第三方系統。由於受網路傳輸、被調系統的效能等多方面的影響,每次呼叫外圍系統都會消耗一定的時間,綜合起來我們一般會計算一個平均值,那麼這個值就是被呼叫系統的平均延時。
線上使用者
Web類的應用一般會有線上使用者這樣一個測試場景。這個場景主要的考察目標是在大量使用者線上的情況下,系統是否會出現異常。線上使用者即登入系統後並未執行任何操作的使用者或執行操作後未退出的使用者。腳本里設定一個足夠長的思考時間,讓使用者反覆執行“登入-線上-退出”這樣的過程。一般這種場景模擬的使用者數量較大。
最優併發使用者
這個場景是為了找到應用的最優併發使用者數量。最優併發使用者數量是指應用達到最大TPS時的併發使用者數量,這一點和最優TPS的定義是有區別的。通常在進行多交易混合容量場景執行過程中測試出應用最大TPS時的併發使用者數量即為最優併發使用者數量,故此場景可以和多交易混合容量場景合併執行。
最大併發使用者
這個場景是為了找到應用能夠承受的最大併發使用者數量。最大併發使用者數量是應用能夠承受的併發使用者的極限,這時要求使用者不會出現失敗,交易響應時間不能超過指標的要求,應用不會出現異常、錯誤等非正常現象。在測試過程中,當我們測試到最大TPS後繼續增加併發使用者數量,直到出現應用異常,或出現併發使用者失敗,或交易響應時間超過測試指標要求等,這時的併發使用者數量即為最大併發使用者。
對於最優併發使用者或最大併發使用者的場景,一般測試web類的應用或有明確併發使用者指標需求的應用時會設計這樣的測試場景,而介面類的應用一般不考慮這兩個場景。
梯度加壓
所謂梯度是指開始使用較少的使用者加壓一段時間(幾分鐘即可),待TPS穩定後再繼續往上加使用者,如此迴圈,直到TPS不再增加為止。整個過程就像爬樓梯一樣,所以稱為“梯度”。
這種型別場景一般是為了“偷懶”而設計的。比如,在生產環境要測試一個交易的最大TPS能夠到多少時,我們為了節省寶貴的測試時間,一般會使用梯度加壓的場景策略。這時我們不知道被測環境能夠達到什麼樣的吞吐量,也沒有明確的測試指標,為了快速找到應用的最大TPS,使用梯度場景是最簡單有效的。另外,梯度場景適合獨立交易的應用(壓測場景只有一個交易),因為獨立交易不必考慮複雜的場景設定,使用梯度場景可以節省大量的測試執行時間。