要進行的性能測試的類型取決於想要達到的結果。例如,對於可再現性,基准測試是最好的方法。而要從當前用戶負載的角度測試系統的上限,則應該使用容量規划測試。
如果不進行合理的規划進行性能測試將會是一項混亂的任務。因為對於任何的軟件開發流程,都必須收集需求,理解業務需要,並在進行實際測試之前設計出正式的進度表。性能測試的需求由業務需要驅動,並由一組用例闡明。這些用例可以基於歷史數據(例如服務器一周的負載模式)或預測的近似值。弄清楚需要測試的內容之后,就需要知道如何進行測試了。
在開發階段前期,應該使用基准測試來確定應用程序中是否出現性能倒退。基准測試可以在一個相對短的時間內收集可重復的結果。進行基准測試的最好方法是,每次測試改變一個且只改變一個參數。
開發階段后期,在應用程序中的bug已經被解決,應用程序達到一種穩定狀態之后,可以運行更為復雜的測試,確定系統在不同負載模式下的表現。這些測試被稱為容量規划測試、滲入測試(soak test)、峰谷測試(peak-rest test),它們旨在通過測試應用程序的可靠性、健壯性和可伸縮性來測試接近於現實世界的場景。
基准測試
基准測試的關鍵是要獲得一致的、可再現的結果。可再現的結果有兩個好處:減少重新運行測試的次數;對測試的產品和產生的數字更為確信。使用性能測試工具可能會對測試結果產生很大影響。假如測試的兩個指標是服務器的響應時間和吞吐量,它們會受到服務器上的負載的影響。服務器上的負載受兩個因素影響:同時與服務器通信的連接(或虛擬用戶)的數目,以及每個虛擬用戶請求之間的考慮時間的長短。很明顯,與服務器通信的用戶越多,負載越大。同樣,請求之間的考慮時間越短,負載也越大。這兩個因素的不同組合會產生不同服務器負載等級。隨着服務器上負載的增加,吞吐量會不斷攀升,直到到達一個點穩定下來。在某點上,執行隊伍開始增長,因為服務器上所有的線程都已投入使用,傳入的請求不再被處理,而是放入隊列中,當線程空閑時再處理。最初的一段時間,執行隊列的長度為零,然后就開始以穩定的速度增長。這是因為系統中的負載在穩定增長,雖然最初系統有足夠的空閑線程區處理增加的負載,最終它還是不能承受,必須將其排入隊列。當系統達到飽和點,服務器吞吐量保持穩定后,就達到了給定條件下的系統上限。但是隨着服務器負載的增長,系統響應時間隨之延長,雖然吞吐量保持穩定。
為了獲得真正可再現的結果,應將系統置於相同的高負載下。為此,與服務器通信的虛擬用戶應該將請求之間的考慮時間設為零。這樣服務器會立即超載,並開始構建執行隊列。如果請求(虛擬用戶)數保持一致,基准測試的結果應該會非常精確,完全可以再現。對於一次給定的測試,應該取響應時間和吞吐量的平均值。精確獲得這些值的唯一方法是一次加載所有用戶,然后在預定的時間段內持續運行。這稱為flat測試。
與此對應的時ramp-up測試,用戶是交錯上升的,每幾秒增加一些新用戶。Ramp-up測試不能產生精確和可重現的平均值,這是因為由於用戶的增加時每次一部分,系統負載在不斷地變化。因此flat測試時獲得基准測試數據的理想模式。實際上,ramp-up測試對於找出以后要運行的flat測試的范圍非常有用。Ramp-up測試的優點是,可以看出隨着系統負載的改變,測量值是如何改變的。然后可以據此選擇以后要運行的flat測試的范圍。
Flat測試的問題是系統會遇到波動效果。波動出現后,吞吐量不再是平滑的。這在系統的各個方面都有所體現,包括CPU的使用量。此外執行隊列也承受着不穩定的負載,因此可以看到,隨着系統負載的增加和減少,執行隊列也在增長和縮減。每隔一段時間就會出現一個波形,事物的響應時間也類似,只不過效果隨着時間推移逐漸減弱。當測試中所有用戶都執行幾乎相同的操作時,就會發生這種現象。這將會產生非常不可靠和不精確的結果,所以必須采取一些措施防止這種情況的出現。有兩種方法可以從這種類型的結果中獲得精確的測量值。如果測試可以運行相當長的時間,最后由於隨機事件的本性使然,服務器的吞吐量會被拉平。或者,可以只選取波形中兩個平息點之間的測量值。該方法缺點是可以捕獲數據的時間非常短。
性能規划測試
對於性能規划類型的測試來說,其目標是找出,在特定的環境下,給定的應用程序的性能可以達到何種程度。此時可重現性就不如在基准測試中那么重要了,因為測試中通常都會有隨機因子。引入隨機因子的目的是為了盡量模擬具有真實用戶負載的現實世界應用程序。通常,具體目標是找出系統在特定的服務器響應時間下支持的當前用戶的最大數。
要確定系統的容量,需要考慮幾個因素。通常,服務器的用戶總數非常大(以十萬計),但是實際上,這個數字並不能說明什么。真正需要知道的是,這些用戶中有多少是並發與服務器通信的。其次要知道的是,每個用戶的考慮時間是多少。這非常重要,因為考慮時間越短,系統所支持的並發用戶越少。在現實世界中,很難確定用戶的考慮時間,通常用戶也不會精確的按照時間間隔發出請求。
於是就引進了隨機性。如果知道普通用戶的考慮時間是5秒,誤差20%,那么在設計負載測試時,就要確保請求的時間為5X(1+/-20%)秒。此外可以利用調步的理念向負載場景中引入更多的隨機性。即在一個虛擬用戶完成一整套的請求后,該用戶暫停了一個設定的時間段,或者一個小的隨機時間段,例如2X(1+/-25%)秒,然后再繼續執行下一套請求。將這兩種隨機變化方法運用到測試中,可以提供更接近於現實世界的場景。
進行容量規划測試時,加載用戶模擬負載狀態的最好方法是模擬高峰時間用戶與服務器通信的狀況。這種用戶負載狀態是在一段時間內逐步達到的話則使用ramp-up類型的測試,否則用flat類型的測試。兩種不同類型的測試會產生沒有可比性的不同測試。例如,如果系統進行ramp-up測試,系統可以以每4秒或更短的響應時間支持5000用戶。而執行flat測試,對於5000用戶,系統的平均響應時間要大於4秒。這是由於ramp-up測試固有的不准確性使其不能顯示系統可以支持的並發用戶的精確數字。以門戶應用程序為例,隨着門戶規模的擴大和集群規模的擴大,這種不確定性就會隨之顯現。這不是說不應該使用ramp-up測試。對於系統負載在一段比較長的時間內緩慢增加的情況,ramp-up測試效果還是不錯的。這是因為系統能夠隨着時間不斷調整。如果使用快速ramp-up測試,系統就會滯后,從而報告一個較相同用戶負載的flat測試低的響應時間。那么,什么是確定容量的最好方法?結合兩種負載類型的優點,並允許一系列的測試,就會產生最好的結果。例如,首先使用ramp-up測試確定系統可以支持的用戶范圍,確定范圍后,以該范圍內不同並發用戶負載進行一系列的flat測試,更精確地確定系統容量。
滲入測試
滲入測試是一種比較簡單的性能測試。滲入測試所需時間較長,它使用固定數目的並發用戶測試系統的總體健壯性。這些測試將會通過內存泄露、增加的垃圾收集(GC)或系統的其他問題,顯示因長時間運行而出現的任何性能降低。測試運行的時間越久,測試者就對系統越了解。可以運行兩次測試,一次使用較低的負載(要在系統容量之下,以便不會出現執行隊列),一次使用較高的負載(以便出現積極的執行隊列)。
測試應該運行幾天的時間,以便真正了解應用程序長期健康狀況。要確保測試的應用程序盡可能接近現實世界真實情況,用戶場景也要逼真(虛擬用戶通過應用程序導航的方式要與現實世界一致),從而測試應用程序的全部特性。
峰谷測試
峰谷測試兼有容量規划ramp-up類型測試和滲入測試的特征。其目標是確定從高負載(例如系統高峰時間的負載)恢復、轉為幾乎空閑、然后再攀升到高負載、再降低的能力。實現這種測試的最好方法是,進行一系列的快速ramp-up測試,繼之以一段時間的平穩狀態(取決於業務需求),然后急劇降低負載,此時可令系統平息一下,然后再快速ramp-up。反復這個過程。這樣可以確定兩個事項:第二次高峰是否可重現第一次峰值?其后的每次高峰是等於還是大於第一次峰值?在測試過程中,系統是否顯示了內存或GC性能降低的有關跡象。測試運行(不停重復峰值/空閑周期)的時間越長,就會對系統健壯性越了解。