性能測試之並發壓力
來自專欄 ROAD-測試
上周跟一朋友闡述性能中並發的概念,嘰里咕嚕一大通,完了興緻勃勃地讓她總結一下,她說了一句:感覺你研究的東西太初級,並發這種概念,太簡單,沒什麼好說的。我聽了差點沒暈倒,估計她也暈了,真是失敗。
並發真的這麼簡單?性能真的如我們所理解的那樣?
也許並不像我們想像的那麼簡單,之所以我們去探究這些基本的概念,是因為在實際的工作中,我們發現,很多問題到最後才發現,根源在於概念沒有統一,抑或沒有理解,而無論作為研發人員,還是顧問、銷售人員,我們除了自己理解,還需要與客戶交流溝通,因此,深刻理解並能通俗易懂的表達出來是非常重要的。
由於軟體性能的範圍比較大,我們將選取幾個典型的問題進行探究,相關概念的理解與分析將逐步進行公開。
● 如何考察性能
這個問題相信很多同事都瞭然於心了,基本都有自己的理解,我們也很少接到不懂性能的反饋,但很多人甚至包括客戶,都把響應時間或者並發用戶作為衡量性能的惟一依據,支持10000並發?性能好!響應時間1秒?性能好!有些時候我們也會接到客戶一些要求,讓我們哭笑不得,某次一客戶就要求我們的產品支持10000並發,有點汗,哈哈。
實際上性能是一項工程,嚴格地說,性能是在某一個特定環境下,系統所表現出來的最大事務處理能力。如果我們將這個問題細化,性能取決於具體環境,取決於系統架構,取決於軟體與伺服器的優化等等,也就是,我們所提供的內部測試報告是具備一定的前提的(在一定的網路或硬體環境下),如果我們的架構是包含了10台機器的集群,而客戶方提供的卻是2台PC機,這種條件下還要求測試結果保持一致,就有點為難了。
儘管性能有很多範圍、指標、概念,比如響應時間、吞吐量、並發用戶、軟硬體負荷等等,但對普通用戶來說,並發用戶數與響應時間這兩個概念還是最為直觀與普通,認可度也最高,搞清楚這兩個概念非常重要。後面我們會逐步闡述其他概念。
● 理解壓力
在談起並發這個概念之前,我們先來說說壓力,對系統而言,性能問題歸根到底,都會體現為實實在在的壓力。因此,我們一般說的「你這個系統的性能最高能到多少?」,其內在含義指的就是「系統所能承受的最大壓力是多少」。
那麼壓力究竟是什麼呢?
我突然想起天天坐的地鐵,沒有比坐地鐵這件事情更便於形容性能與壓力了,哈哈。話說我每天在立水橋南上地鐵,絕對是考驗體力耐力心理素質的事情啊(說岔了)。
我們可以把一班地鐵列車看成是一個被測的系統,對於這個系統而言,其壓力顯而易見,就是列車中所有的人,比如北京地鐵5號線,每列車的定員人數是1424人,摺合每節車廂237人(當然包括站著的),而最多容納是1820人,摺合每車廂303人,這個總承受人數。
其實就是系統(也就是列車)的最大設計承受壓力(也就是吞吐量了),當然,北京地鐵比較變態,超員現象比較嚴重,我每天佔用的面積還不超過10平方厘米(腳踮起來了),實際最大負荷估計超過2000了。對列車而言,超過最大負荷是比較危險的,要麼是拉不動(這個估計可能性不大),要麼人擠壞(君不見每天爭吵哀嚎無數)。
如果超出設計負荷值,系統就會存在危險,危險是多方面的,因此,一般的,系統應該具備超出負荷的處理預案,對照到地鐵,高峰時期就會進行限流。
搞清楚這個問題後,再來看看常規的系統,就好理解了,系統的壓力是什麼呢?壓力是對被測系統而言的,只要系統在處理事務,就有壓力,這種壓力不僅僅體現在網路上(數據的吞吐),還體現在伺服器上(如CPU、內存等),因此,我們不要混淆了吞吐量與壓力的關係,應該這麼說,在一些web系統上,吞吐量可以在一定程度上反映系統承受的數據壓力。
另外,我們需要清楚,壓力不等於性能,壓力只是檢驗性能的一種手段,對一個性能良好的系統,在一定的壓力下,應該可以保持正常運轉,如果超過負荷,則應該分流或化解壓力,這也是我們需要檢驗的。
● 理解並發
說完壓力,我們已經知道,壓力其實就是一種作用力,當然,還可以理解為一種量的度量,比如列車的承載數,既然有量,就肯定有速度,承載總量(吞吐量)是一定的,但速度卻是變化的,我們早晚高峰的時候去乘地鐵,當然是擁擠非常,但如果你晚上11點去做地鐵,我可以很高興地告訴你,你還會有座位!
原因在於,早晚高峰時坐地鐵的人多,深夜時坐地鐵的人少(這不是廢話嗎)。我們再來想想,高峰的時候可能同一時間擠進門的人很多,基本上門有多大,同時擠進去的人就能把門給塞滿。
那麼這個並發(虛擬用戶)是什麼呢?
並發是有場景條件的,要看我們考察的是什麼事情,我們再來想像一下地鐵,在整個地鐵大廳里(包括列車),有剛剛進站的,有正在買票的,有正在登車的,有坐在車上的,還有閑逛的,這麼多人,但對列車有壓力的,其實就是已經在車上的這些人(包括擠車的),如果我們考察性能的系統就是列車,很顯然,重點關心的就只需要看看車上現有的這些人。
再次強調,並發跟考察的具體場景是有關係的,即並發做什麼,並發這個詞,原始的翻譯是concurrent,意為同時發生的,或同時存在的。至於同時做什麼,要看我們定義了,同時在地鐵大廳里,同時在地鐵上,同時在擠地鐵,考察的事情不一樣,並發的意義就不一樣。
對地鐵這個系統而言,每個時間都有新來的人,也有走的人,大家做的事情基本都相同,乘地鐵。假定某個時刻地鐵大廳中有10000人,檢票口候車的有100人,剛剛開走的地鐵上乘有2000人,那此時對考察的系統(列車)而言,並發就是2000人,而如果考察的是檢票處,則並發為100人,同樣,如果考察的系統是地鐵大廳,那此時的並發就是10000人。這種並發我們一般稱之為「廣義並發」。
廣義並發有點類似與通常我們所說的在線用戶,但存在關鍵的區別,即並發用戶針對的是某一件事務,譬如註冊、登錄、上傳、瀏覽等,而在線用戶是一個很泛的概念,一般包括前面所述的所有事務,可以理解為一個事務集合。
在性能的理論中,還有一個概念,simultaneously,翻譯為同步的,當前,為方便計算,我們一般把「同步」理解為「同1秒」,也就是說,這個同步的就是單位時間內發生的數量。也即我們通常所說的「狹義並發」。需要注意的是,實際的測試中經常會遇到被測事務響應時間低於這個1秒的單位時間,此時的並發計算仍需要按1秒計算,具體參見「我們的定義」中的說明。
很多時候,我們(特別是客戶)往往搞混了這兩個並發的概念。對系統來說,廣義的並發實際上是在一個時間內操作事務的虛擬用戶,而狹義的並髮指的是單位時間內向系統發起請求的虛擬用戶,前者是「存在」,後者是「請求」,勿容置疑,壓力不僅僅受成功發出請求的用戶帶來的壓力,同時也受「存在」的用戶影響。
換種理解方式,並發考察的是系統的處理能力,最多能支持多少用戶同時處理某件事務,而不是壓力發出端發出的請求。
除此之外,並發作為一個量化的指標,是對應著具體的取值的,因此,很多系統會去尋求最大並發,實際上,我們來回顧5號線的承載力的例子,核定載客1424人,這種情況可能考慮到乘客的感受(還算舒服,站著也算,哈哈)
● 理解我們的定義
在我們已經做過的很多測試中,都有並發這個概念,當然也包括我們很多開發人員,所謂的並發是怎麼定義的呢?
客觀的說,我們的定義比較接近於「廣義並發」,但有所不同。這與我們的考察對象(web系統)、衡量事務(通常我們衡量的都是單個事務,很少把多個事務放在一起處理,原因在於盡量避免事務的耦合性所帶來的影響)有關,具體到地鐵的例子,如果我們考察的系統指「地鐵大廳」,那麼我們所謂的並發一般通常指同時進入地鐵大廳的人。而如果我們考察的系統指「地鐵列車」,那麼我們所謂的並發則指同時進入站台的人。
在實際的產品測試中,比如我們在測試IDS登錄的時候,如果說,支持800並發,其涵義為「支持800個虛擬用戶同時進行登錄操作」,需要說明的是,這個同時並非指同一秒,要知道,並發本身是沒有單位的。在800並發下的結果如何,要看響應時間,這個問題本文不進行仔細闡述。如有興趣可以參考相關資料。
測試中,我們也會考慮「狹義並發」的情況,但狹義並發需要考慮到被測系統的入口,比如,假定地鐵總共有10個入口且全部開放,每個入口只能容納1個人進出,則「狹義並發」下最大值就是10?不一定!因為我們還沒有考慮速度問題,前面提到,狹義並發的單位是秒,如果每個人通過每個入口的耗時就是1s,則最大「狹義並發」值就是10,如果通過的時間少於1秒呢?還是按1秒算,比如還是這個情景,乘客通過入口的耗時假定為0.1秒,則最大狹義並發就是10/0.1=100了。
簡單點說,我們可以這麼理解實際工作中的並發,被測的事務總得有人(其實就是虛擬的用戶)來做,對吧,同時允許多少用戶來做這件事情呢?這個多少用戶就是我們需要的並發值。
● 如何估算並發
那麼我們如何來估算這個並發值呢?
在此我們需要作出說明,一般我們需要的數據應該來自於實際數據(比如系統日誌的記錄),這樣最可靠,只有當系統新啟動且無任何數據參考的時候我們才需要進行估算。
比如我們測試地鐵大廳的性能情況,該如何去估算當乘客進入大廳時,地鐵大廳的性能呢?下面以筆者經常乘坐的地鐵5號線立水橋南站為例進行估算,過程與數據僅供參考。
假定每天從該站乘坐地鐵的人數為5萬人次,每天的早高峰為7-9點,晚高峰為6-7點,根據8/2原則,80%的乘客(人次)會在高峰期乘坐該站的地鐵,則平均每秒到達地鐵檢票口的人數為(50000×80%)/(3×60×60) = 3.7~=4人,當然這個4人不能作為計算所用的並發值,因為對此時的受壓入口檢票口來說,4隻是每秒到達的壓力(即請求)數量,考慮到安檢、入口關閉等因素,實際堆積在檢票口的人數可能要大於這個數目,假定每個人需要3秒左右才能入站,則實際並發應該為(4人/秒)×3秒=12。當然我們必須指出,這種方法得到的情況並非極端值,因為即使作為早晚高峰,人數的分布也不是平均的(具體情況需要根據實際數據進行分析),但對大部分系統的大部分場景,我們可以用(用戶總量/統計時間)×影響因子(一般為3,為經驗係數)來進行估算。
實際上,還有一種估算方法,而這種估算方法為國內眾多書籍、文章反覆轉載,其來源與Eric Man Wong在2004年公布的一篇「論文」《Method for Estimating the Number of Concurrent Users》,其核心公式如下:
C=nL/T
其中,C代表在線用戶,n代表執行事務的用戶總數,L代表每用戶的平均在線時間,T為待統計的總時間,依舊以地鐵入站的情況進行估算,依舊考慮8/2原則,即n為50000*80%人,T為3小時,L即我們在地鐵中停留的時間(從進站到上車),假定為5分鐘,因此得到的公式為:
C=(50000人×80%×5min)/3×60min = 1111
並發數是1111,比前面一種演算法要高的多,這是為什麼呢?
實際上,後面這種統計方法是由一定的局限性與適用範圍的,對其統計的每個並發用戶而言,每個用戶所在線的時間(如上面的5min),並不一定是我們所需要的場景耗時,該5分鐘應該是整個大場景(如從進站到離開),而我們通常所使用的場景往往包含了一連貫的子場景,如進站、等待、上車等,因此,如果我們測試的場景是某一個具體的動作,不建議採用這種公式(當然,如果單獨為每個動作估算時間也是可以的。)
從本質上來說,兩種公式的統計,結果都是一樣的,關鍵取決與統計口徑。
極限的問題也是我們需要考慮的,數據的估算往往是一個大的工程,涉及到很多複雜的情況,比如用戶的進入與離開,人流異常等,因此我們考慮的多為常規的情況,在一些特殊的情況下,用戶的峰值往往要大很多,此時需要去對極限情況下進行估算。
此時的目的在於檢查系統的極限承載情況,如列車最大承載2000人,站內極限承載10000人是一樣的,超出這個極限,就需要採取一些緊急措施,比如限流(對應到普通的系統,就是設置最大連接數,超出的必須等待)之類。
這種值的計算,不可能給出準確值,可以根據實際情況,協商而定,比如把經驗係數更改為5,這種情況下,如果有日誌或者統計數據予以支撐,會更加精確。
● 回答客戶的疑惑
面對客戶,經常需要去解答一些問題,常見的幾類疑惑如下:
1、客戶堅持要求並發2000,怎麼辦?
這個問題非常關鍵,即上面所謂的闡述只是為了讓大家對並發等概念有個大體的理
解,但我們的工作重心不是一來就跟客戶講理論,而是合理、有效、迅速地完成項目,因此,特別是一些項目的諮詢階段,如果客戶堅持提出達到某個並發要求,我們首先需要看下這個情況產品能否支持,如果不支持,通過修改架構(比如增加伺服器,公司的大部分產品都支持集群)來完成,如果還是沒法達到要求,我們再來跟客戶交流,從客戶能理解的方式,從客戶的角度去計算並發,最後得到認可就行了。當然,解決這些問題,需要我們對公司的產品性能基本比較了解(可以通過產品的性能測試報告來了解,質保將來會考慮出台所有產品的性能指標集合供參考),如果難度還是很大,可以申請質保的支持。大家一起去解決這個問題。
2、你們的系統能支持10000並發嗎?
一些客戶經常提出非常高的並發要求,此類客戶通常對性能並不了解,或者之前有客戶對其做了錯誤的解釋,此時我們需要解釋我們測試並發的概念:同時向伺服器發出請求的虛擬用戶數。(而我們通常會採用嚴格的方法進行場景測試:即採用集合點的方式進行操作。這種方式也即前面介紹的狹義並發的概念。)
另外,並發值需要考慮實際情況,需要根據實際的需求進行計算,與此同時,並發的影響因素並非僅僅是軟體本身,還有網路、架構等等,TRS的產品性能測試往往給出單位機器的性能,用戶可以根據這個基礎值來構造實際架構。
3、你們的系統怎麼才支持200並發?
並發的概念在於同時在處理某一件事情,而且系統一直保持這樣的一個強度,並不是說總共只有200人,另外,我們測試的一般是單機,也就是說,如果更好的性能要求,可以通過集群的方式來獲得更優的結果,目前TRS的產品基本都支持集群的部署架構。需要注意的是,並發的支持除了軟體本身,還受到網路、伺服器性能等多方面原因的影響。
4、是否可以使用每秒處理事務來衡量。
性能測試的衡量指標除了響應時間,還有吞吐量、每秒點擊數、每秒PV、每秒事務處理能力等,因此我們可以通過多種方式進行衡量,在更大意義上,各個指標間也存在一定的內涵聯繫,結合起來考慮更能夠檢查系統的性能。但受制於一些客觀原因(如定製),在之前的報告中,指標衡量存在一定的限制。
5、響應時間與並發、壓力是什麼關係?這麼操作的響應怎麼才6秒,太慢了,你們的產品性能不行啊!
一般的,一定的並發下將對系統造成一定的壓力,而對每個並發(用戶)而言,所體現出來的性能多是直觀的響應時間,在環境一定的情況下,響應時間越快說明系統性能越好。但此處需要清除一個問題,假定一個用戶獲取的響應時間是5秒,這5秒都在對系統產生壓力嗎?
後面這個是一個有趣而有意義的問題,我們知道這個響應時間是從用戶發出請求到接收到響應的為止的總耗時,如果我們使用httpwatch之類的工具,可以很清晰的看到時間消耗的分布區間,我們可以把這個問題比作是向牆壁擊出一個球,從擊出到彈回來的時間即為響應時間。
大家打過壁球嗎?打壁球的過程其實就完美的詮釋了用戶發起請求到接受響應整個過程,可以我們可以把牆壁看作系統,打球者就是用戶,球是用戶發出的請求,擊打一次球包含有三個動作:擊出球、球接觸牆壁、收到彈回的球。三個過程加起來的總時間就是這個請求(打出一發球)所得到的響應,但很顯然,真正對系統產生壓力的動作在於接觸牆壁的時間,大部分的時間消耗在空中,即球在空中飛行時的時間,而這個飛行時間並不受系統控制,對應到常規系統,就很可能是網路在傳輸過程中出現了問題。
這個壁球的例子實際上還可以解釋一些相關的概念,比如並發就是同時擊出多個球,系統(牆壁)所能承受的最大並發壓力就是牆壁的面積所能容納的壁球數量,假定牆壁面積可以容納1000個球,則牆壁瞬間可以接觸的球的數量就是1000個,這個就是狹義並發的概念了,考慮到空中飛行,即將觸碰牆壁的球,理論上的廣義並發值要高於1000。擊球時的力度可以理解為客戶端的性能,性能好發球就快,否則就慢,只要系統性能沒有達到瓶頸(比如牆壁沒有壞),系統的性能是跟客戶端呈正比的,即擊球速度越快,返回越快。
因此,當遇到客戶對響應時間有疑問時,我們需要解釋的重點在於,壓力在於球接觸牆壁的瞬間,但性能測試考核的響應時間確實包含了兩次飛行(發送與接受)的時間,而這個時間是受包含伺服器性能、網路性能、客戶端性能在內的多因素影響的,相信客戶可以理解。
● 簡單的結論
如果您覺得上面說的東西過於繁瑣,以下基本概念可能更適合閱讀。
1、並發分為狹義並發與廣義並發兩種,狹義並髮指同一時間點開始做某件事情,廣義並髮指同一時間段正在做某件事情;
2、並發與被考察的場景是息息相關的,測試中所指的並發一般指同一時間段在做某件事情(被測事務)的用戶數,在嚴格測試的環境下,我們會要求所有用戶在同一時間點集合併執行;
3、在線用戶與並發用戶不是一個概念,在線用戶包含了很多非測試事務用戶、空閑的客戶等,因此不能把在線的用戶全計作並發用戶,一般的並發用戶佔在線用戶總量在10%~20%左右,當然,這個值僅供參考,實際問題需要實際分析。
4、理論上說並發越大性能越好,但其取決與很多因素,比如網路、伺服器數量、伺服器性能、系統架構、軟硬體優化等,另外,並發的計算需要在需求階段根據實際情況進行估算,這樣得到的結果才是合理的。
5、幾個概念的再次說明:
→ 並發用戶數:同時在操作被考察事務的用戶數
→ 在線用戶數:當前被測系統中的活動用戶數(包括考察事務與非考察事務)
→ 平均響應時間:每個用戶操作事務獲得的平均響應時間(算術平均值)
→ 90%響應時間:90%用戶平均響應時間在此值範圍內(取除去10%極高值後的最大值)
→ 平均事務數:單位時間完成的事務數(如登錄、首頁讀取等)
→ 平均吞吐量:單位時間內的數據傳輸量
→ 平均點擊數:單位時間完成的請求數量
→ PV:某時間段內完成的頁面請求數量
推薦閱讀: