標簽(空格分隔): 軟件性能與性能指標
當我們說道性能的時候到底是說的什么?
目前,對軟件性能最普遍的理解就是軟件處理的及時性。但其實,從不同的系統類型,以及不同的視角去討論軟件性能,都會有所區別。
對於不同類型的系統,軟件性能的關注點各不相同,比如:
- Web 類應用和手機端應用,一般以終端用戶感受到的端到端的響應時間來描述系統的性能;
- 非交互式的應用,比如典型的電信和銀行后台處理系統,響應時間關注更多的是事件處理的速度,以及單位時間的事件吞吐量。
這很容易理解。同樣地,對同一個系統來說,不同的對象群體對軟件性能的關注點和期望也不完全相同,甚至很多時候是對立的。這里,不同的對象群體可以分為四大類:終端用戶、系統運維人員、軟件設計開發人員和性能測試人員。
終端用戶是軟件系統的最終使用者,他們對軟件性能的反饋直接決定了這個系統的應用前景;而,軟件開發人員、運維人員、性能測試人員,對性能測試的關注點則直接決定了一個系統交付到用戶手中的性能。
只有全面了解各類群體對軟件系統的不同需求,才能保證這個系統具有真正高可靠的性能。所以,接下來我會從這四類人的視角和維度了解性能;
終端用戶眼中的軟件性能
從終端用戶(也就是軟件系統使用者)的維度來講,軟件性能表現為用戶進行業務操作時的主觀響應時間。具體來講就是,從用戶在界面上完成一個操作開始,到系統把本次操作的結果以用戶能察覺的方式展現出來的全部時間。對終端用戶來說,這個時間越短體驗越好。
- 這個響應時間是終端用戶對系統性能的最直觀印象,包括了系統響應時間和前端展現時間。
- 系統響應時間,反應的是系統能力,又可以進一步細分為應用系統處理時間、數據庫處理時間和網絡傳輸時間等;
- 前端展現時間,取決於用戶端的處理能力。
從這個角度來看,你就可以非常容易理解性能測試為什么會分為后端(服務器端)的性能測試和前端(通常是瀏覽器端)的性能測試了。
系統運維人員眼中的軟件性能
- 從軟件系統運維(也就是系統運維人員)的角度,軟件性能除了包括單個用戶的響應時間外,更要關注大量用戶並發訪問時的負載,以及可能的更大負載情況下的系統健康狀態、並發處理能力、當前部署的系統容量、可能的系統瓶頸、系統配置層面的調優、數據庫的調優,以及長時間運行穩定性和可擴展性。
- 大多數情況下,系統運維人員和終端用戶是站在同一條戰線上的,希望系統的響應速度盡可能地快。但,某些情況下他們的意見是對立的,最常見的情況就是,系統運維人員必須在最大並發用戶數和系統響應時間之間進行權衡取舍。比如,當有兩套系統配置方案可以提供以下系統能力的時:
- 配置方案 A 可以提供 100 萬並發訪問用戶的能力,此時用戶的登錄響應時間是 3 秒
- 配置方案 B 可以提供 500 萬並發訪問用戶的能力,此時用戶的登錄響應時間是 8 秒。
目前,有些系統為了能夠承載更多的並發用戶,往往會犧牲等待時間而引入預期的等待機制。比如,火車票購票網站,就在處理極大並發用戶時采用了排隊機制,以盡可能提高系統容量,但卻增加了用戶實際感受到的響應時間。
軟件設計開發人員眼中的軟件性能
從軟件系統開發(也就是軟件設計開發人員)的角度來講,軟件性能關注的是性能相關的設計和實現細節,這幾乎涵蓋了軟件設計和開發的全過程。
在軟件設計開發人員眼中,軟件性能通常會包含算法設計、架構設計、性能最佳實踐、數據庫相關、軟件性能的可測試性這五大方面。其中,每個方面關注的點,也包括很多。
第一,算法設計包含的點:
- 核心算法的設計與實現是否高效;
必要時,設計上是否采用buffer機制以提高性能,降低I/O;
是否存在潛在的內存泄露;
是否存在並發環境下的線程安全問題;
是否存在不合理的線程同步方式;
是否存在不合理的資源競爭。- 第二,架構設計包含的內容:
站在整體系統的角度,是否可以方便地進行系統容量和性能擴展;
應用集群的可擴展性是否經過測試和驗證;
緩存集群的可擴展性是否經過測試和驗證;
數據庫的可擴展性是否經過測試和驗證。
第三,性能最佳實踐包含的點:
- 代碼實現是否遵守開發語言的性能最佳實踐;
關鍵代碼是否在白盒級別進行性能測試;
是否考慮前端性能的優化;
必要的時候是否采用數據壓縮傳輸;
對於既要壓縮又要加密的場景,是否采用先壓縮后加密的順序。
第四,數據庫相關的點:
- 數據庫表設計是否高效;
是否引入必要的索引;
SQL 語句的執行計划是否合理;
SQL 語句除了功能是否要考慮性能要求;
數據庫是否需要引入讀寫分離機制;
系統冷啟動后,緩存大量不命中的時候,數據庫承載的壓力是否超負荷。
第五,軟件性能的可測試性包含的點:
- 是否為性能分析(Profiler)提供必要的接口支持;
是否支持高並發場景下的性能打點;
否支持全鏈路的性能分析。
需要注意的是,軟件開發人員一般不會關注系統部署級別的性能,比如軟件運行目標操作系統的調優、應用服務器的參數調優、數據庫的參數調優、網絡環境的調優等。
系統部署級別的性能測試,目前一般是在系統性能測試階段或者系統容量規划階段,由性能測試人員、系統架構師,以及數據庫管理員(DBA)協作完成。
性能測試人員眼中的軟件性能
從性能工程的角度看,性能測試工程師關注的是算法設計、架構設計、性能最佳實踐、數據庫相關、軟件性能的可測試性這五大方面。
在系統架構師、DBA,以及開發人員的協助下,性能測試人員既要能夠准確把握軟件的性能需求,又要能夠准確定位引起“不好”性能表現的制約因素和根源,並提出相應的解決方案。
- 一個優秀的性能測試工程師,一般需要具有以下技能:
1.性能需求的總結和抽象能力;
2.根據性能測試目標,精准的性能測試場景設計和計算能力;
3.性能測試場景和性能測試腳本的開發和執行能力;
4.測試性能報告的分析解讀能力;
5.性能瓶頸的快速排查和定位能力;
6.性能測試數據的設計和實現能力;
7.面對互聯網產品,全鏈路壓測的設計與執行能力,能夠和系統架構師一起處理流量標記、影子數據庫等的技術設計能力;
8.深入理解性能測試工具的內部實現原理,當性能測試工具有限制時,可以進行擴展二次開發;
9.極其寬廣的知識面,既要有“面”的知識,比如系統架構、存儲架構、網絡架構等全局的知識,還要有大量“點”的知識積累,比如數據庫 SQL 語句的執行計划調優、JVM 垃圾回收(GC)機制、多線程常見問題等等。
- 現在,我再來和你說說衡量軟件性能的三個最常用的指標:
並發用戶數、
響應時間,
以及系統吞吐量。
只要你接觸過性能測試,或者你的團隊開展過性能測試,你都應該聽說這三個指標。但其實很多人對它們的理解還都停留在表面,並沒有深入細致地考慮過其本質與內涵,這也導致了性能測試很多時候並沒有發揮應有的作用。
並發用戶數
並發用戶數,是性能需求與測試最常用,也是最重要的指標之一。它包含了業務層面和后端服務器層面的兩層含義。
- 業務層面的並發用戶數,指的是實際使用系統的用戶總數。但是,單靠這個指標並不能反映系統實際承載的壓力,我們還要結合用戶行為模型才能得到系統實際承載的壓力。
- 后端服務器層面的並發用戶數,指的是“同時向服務器發送請求的數量”,直接反映了系統實際承載的壓力。
為了讓你更好地理解這兩層含義之間的區別,我們先一起來看一個實例:一個已經投入運行的 ERP 系統,該系統所在企業共有 5000 名員工並都擁有賬號,也就是說這個系統有 5000 個潛在用戶。
根據系統日志分析得知,該系統最大在線用戶數是 2500 人,那么從宏觀角度來看,2500 就是這個系統的最大並發用戶數。但是,2500 這個數據僅僅是說在最高峰時段有 2500 個用戶登錄了系統,而服務器所承受的壓力取決於登錄用戶的行為,所以它並不能准確表現服務器此時此刻正在承受的壓力。
假設在某一時間點上,這 2500 個用戶中,30% 用戶處於頁面瀏覽狀態(對服務器沒有發起請求),20% 用戶在填寫訂單(也沒有對服務器發起請求),5% 用戶在遞交訂單,15% 用戶在查詢訂單,而另外的 30% 用戶沒有進行任何操作。那么此時,這 2500 個“並發用戶”中真正對服務器產生壓力的只有 500 個用戶((5%+15%)*2500=500)
在這個例子中,5000 是最大的“系統潛在用戶數”,2500 是最大的“業務並發用戶數”,500 則是某個時間點上的“實際並發用戶數”。而此時這 500 個用戶同時執行業務操作所實際觸發的服務器端的所有調用,叫作“服務器並發請求數”。
從這個例子可以看出,在系統運行期間的某個時間點上,有一個指標叫作“同時向服務器發送請求的數量”,這個“同時向服務器發送請求的數量”就是服務器層面的並發用戶數,這個指標同時取決於業務並發用戶數和用戶行為模式,而且用戶行為模式占的比重較大。
因此,分析得到准確的用戶行為模式,是性能測試中的關鍵一環。但,獲得精准的用戶行為模式,是除了獲取性能需求外,最困難的工作。
- 目前,獲取用戶行為模式的方法,主要分為兩種:
1.對於已經上線的系統來說,往往采用系統日志分析法獲取用戶行為統計和峰值並發量等重要信息;
2.而對於未上線的全新系統來說,通常的做法是參考行業中類似系統的統計信息來建模,然后分析。
響應時間
通俗來講,響應時間反映了完成某個操作所需要的時間,其標准定義是“應用系統從請求發出開始,到客戶端接收到最后一個字節數據所消耗的時間”,是用戶視角軟件性能的主要體現。
- 響應時間,分為前端展現時間和系統響應時間兩部分。其中,前端時間,又稱呈現時間,取決於客戶端收到服務器返回的數據后渲染頁面所消耗的時間;而系統響應時間,又可以進一步划分為 Web 服務器時間、應用服務器時間、數據庫時間,以及各服務器間通信的網絡時間。
- 除非是針對前端的性能測試與調優,軟件的性能測試一般更關注服務器端。但是,服務器端響應時間的概念非常清晰、直接,就是指從發出請求起到處理完成的時間,沒有二義性;而前端時間的定義,在我看來存在些歧義。所以,接下來我會和你詳細聊聊前端時間這個話題。
- 雖然前端時間一定程度上取決於客戶端的處理能力,但是前端開發人員現在還會使用一些編程技巧在數據尚未完全接收完成時呈現數據,以減少用戶實際感受到的主觀響應時間。也就是說,我們現在會普遍采用提前渲染技術,使得用戶實際感受到的響應時間通常要小於標准定義的響應時間。
- 鑒於此,我認為響應時間的標准定義就不盡合理了,尤其是對於“接收到最后一個字節”。
我來舉個實際案例吧。加載一個網頁時,如果 10 秒后還是白屏,那你一定會感覺很慢、性能無法接受。但是,回想一下你曾經上新浪網的經歷,當加載新浪首頁時,你應該不會感覺速度很慢吧。其實,實際情況是,新浪首頁的加載時間要遠大於 10 秒,只是新浪采用了數據尚未完全接收完成時進行呈現的技術,大大縮短了用戶主觀感受到的時間,提升了用戶體驗。
所以,嚴格來講,響應時間應該包含兩層含義:技術層面的標准定義和基於用戶主觀感受時間的定義。而在性能測試過程中,我們應該使用哪個層面的含義將取決於性能測試的類型。顯然,對於軟件服務器端的性能測試肯定要采用標准定義,而對於前端性能評估,則應該采用用戶主觀感受時間的定義。
當然,我們在前端性能測試中,會利用一些事件的觸發(比如 DOM-Load、Page-load 等)來客觀地衡量“主觀的前端性能”。
系統吞吐量
系統吞吐量,是最能直接體現軟件系統負載承受能力的指標。
這里需要注意的是,所有對吞吐量的討論都必須以“單位時間”作為基本前提。其實,我認為把“Throughput”翻譯成吞吐率更貼切,因為我們可以這樣理解:吞吐率 = 吞吐量 / 單位時間。但既然國內很多資料已經翻譯為了“吞吐量”,所以通常情況下我們不會刻意去區分吞吐量和吞吐率,統稱為吞吐量。
- 性能測試而言,通常用“Requests/Second”“Pages/Second”“Bytes/Second”來衡量吞吐量。當然,從業務的角度來講,吞吐量也可以用單位時間的業務處理數量來衡量
以不同方式表達的吞吐量可以說明不同層次的問題。比如:
- “Bytes/Second”和“Pages/Second”表示的吞吐量,主要受網絡設置、服務器架構、應用服務器制約;
- Requests/Second”表示的吞吐量,主要受應用服務器和應用本身實現的制約。
這里需要特別注意的是:雖說吞吐量可以反映服務器承受負載的情況,但在不同並發用戶數的場景下,即使系統具有相近的吞吐量,但是得到的系統性能瓶頸也會相差甚遠。
- 比如,某個測試場景中采用 100 個並發用戶,每個用戶每隔 1 秒發出一個 Request,另外一個測試場景采用 1000 個並發用戶,每個用戶每隔 10 秒發出一個 Request。顯然這兩個場景具有相同的吞吐量, 都是 100 Requests/second,但是兩種場景下的系統性能拐點肯定不同。因為,兩個場景所占用的資源是不同的。
這就要求性能測試場景的指標,必然不是單個,需要根據實際情況組合並發用戶數、響應時間這兩個指標。
總結
- 首先,我從終端用戶、系統運維人員、軟件設計開發人員和性能測試人員,這四個維度介紹了軟件系統的性能到底指的是什么:
終端用戶希望自己的業務操作越快越好;
系統運維人員追求系統整體的容量和穩定;
開發人員以“性能工程”的視角關注實現過程的性能;
性能測試人員需要全盤考量、各個擊破。- 然后,介紹了軟件性能的三個最常用的指標:並發用戶數,響應時間,系統吞吐量:
並發用戶數包含不同層面的含義,既可以指實際的並發用戶數,也可以指服務器端的並發數量
;響應時間也包含兩層含義,技術層面的標准定義和基於用戶主觀感受時間的定義;
系統吞吐量是最能直接體現軟件系統承受負載能力的指標,但也必須和其他指標一起使用才能更好地說明問題。