一文搞懂性能測試

性能測試概念

我們經常看到的性能測試概念,有人或稱之爲性能策略,或稱之爲性能方法,或稱之爲性能場景分類,大概可以看到性能測試、負載測試、壓力測試、強度測試等一堆專有名詞的解釋。

針對這些概念,我不知道你看到的時候會不會像我的感覺一樣:亂!一個小小的性能測試,就延伸出了這麼多的概念,並且概念之間的界限又非常模糊。

就拿“壓力測試”、“容量測試”和“極限測試”這三個概念來說吧。

網上針對這三個名詞的解釋是這樣的:

壓力測試

壓力測試是評估系統處於或超過預期負載時系統的運行情況。壓力測試的關注點在於系統在峯值負載或超出最大載荷情況下的處理能力。在壓力級別逐漸增加時,系統性能應該按照預期緩慢下降,但是不應該崩潰。壓力測試還可以發現系統崩潰的臨界點,從而發現系統中的薄弱環節。

容量測試

確定系統可處理同時在線的最大用戶數,使系統承受超額的數據容量來發現它是否能夠正確處理。

極限測試

在過量用戶下的負載測試。

“壓力測試是在超過預期負載時系統的運行情況”,“容量測試是使系統承受超額的數據容量來發現它是否能夠正確處理”。

來吧,就算我語文不好,我也認字的,誰能告訴我這兩者的區別是什麼?除了字不一樣。

如果再抽象一層說一下這些概念,那就是,這些概念都在描述性能測試的不同側面。而這些側面本身構不成策略,構不成方法,不能說是概念,也不能說是理論。

此文一出,肯定會有人說,既然你評價當前的概念混亂,那你有什麼好建議呢?作爲可能被集體轟炸的話題,既然已經擺上了檯面,我還是要冒死給一個自己認爲的合理定義:

性能測試針對系統的性能指標,建立性能測試模型,制定性能測試方案,制定監控策略,在場景條件之下執行性能場景,分析判斷性能瓶頸並調優,最終得出性能結果來評估系統的性能指標是否滿足既定值。

這是我覺得唯一合理的概念定義,下面我就把這個概念詳細解釋一下。

性能測試需要有指標

有人說,我們在做項目的時候,就沒有指標,老闆只說一句,系統壓死爲止。聽起來很兒戲,但這樣的場景不在少數。在我看來,把系統壓死也算是一種指標。至於你用什麼手段把系統“壓死”,那就是實現的問題了。你可以採用很多種手段,告訴老闆,這系統還沒壓就死了! 這也是你的貢獻。

而對“有指標”這個定義來說,理論上合理的,並且應該有的指標是:時間指標、容量指標和資源利用率指標。

而這裏的指標又會有細分,細分的概念又是一團亂。這個話題我們後面再描述。

性能測試需要有模型

模型是什麼?它是真實場景的抽象,可以告訴性能測試人員,業務模型是什麼樣子。比如說,我們有100種業務,但不是每個業務都需要有併發量,可能只有50個業務有,那就要把這些有併發的業務統計出來,哪個業務併發多,哪個業務併發少,做壓力時就要控制好這樣的比例。

這種做法需要的數據通常都是從生產環境中的數據中統計來的,很多在線上不敢直接壓測的企業都是這樣做的。

而隨着互聯網中零售業、雲基礎架構的全面發展,有些企業直接在線上導流來做性能測試,這種思路上的轉變來源於架構的發展及行業的真實需要。但這並不能說明性能測試不需要模型了,因爲這個模型已經從生產流量中導過來了。這一點,還是需要你認清的。

但是對於其他的一些行業,比如銀行這類金融機構,線上一個交易都不能錯。像上面這樣做的難度就太大了。所以這些行業中,仍然需要在測試環境中用業務模型來模擬出生產的流量。

同時也請你認清一點,現在的全鏈路壓測,並沒有像吹噓得那麼神乎其神,很多企業也只是在線上的硬件資源上做壓力而已,並不是真正的邏輯鏈路修改。

我在工作中經常會被問到,性能流量直接從生產上導的話,是不是就可以不用性能測試人員了?性能測試人員就要被淘汰了?

這未免太短視了,大家都盯着最新鮮的技術、方法、概念,各層的領導也都有自己的知識偏好,萬一做了一個決定,影響了最終的結果,有可能會讓很多人跟着受罪。

我之前帶過的一個團隊中,開發架構們一開始就規劃了特別詳細的微服務架構,說這一套非常好。我說這個你們自己決定,我只要在這裏面拿到可用的結果就行。結果開發了不到兩個月,一個個微服務都被合併了,還得天天加班做系統重構,只留了幾大中臺組件。這是爲什麼呢?因爲不適用呀。

同理,性能測試也要選擇適合自己系統業務邏輯的方式,用最低的成本、最快的時間來做事情。

性能測試要有方案

方案規定的內容中有幾個關鍵點,分別是測試環境、測試數據、測試模型、性能指標、壓力策略、准入準出和進度風險。基本上有這些內容就夠了,這些內容具體的信息還需要精準。

你可能會說,怎麼沒有測試計劃?我的建議是,用項目管理工具單獨畫測試計劃,比如用Project或OmniPlan之類的工具。這是因爲在方案中,寫測試計劃,基本上只能寫一個里程碑,再細化一點,就是在裏面再加幾個大階段的條目。但是用項目管理工具做計劃就不同了,它不僅可以細分條目,還能跟蹤各個工作的動態進度,可以設置前後依賴關係,填入資源和成本以便計算項目偏差。

性能測試中要有監控

這個部分的監控,要有分層、分段的能力,要有全局監控、定向監控的能力。關於這一點,我將在第三模塊詳細說明。

性能測試要有預定的條件

這裏的條件包括軟硬件環境、測試數據、測試執行策略、壓力補償等內容。要是展開來說,在場景執行之前,這些條件應該是確定的。

有人說,我們壓力中也會動態擴展。沒問題,但是動態擴展的條件或者判斷條件,也是有確定的策略的,比如說,我們判斷CPU使用率達到80%或I/O響應時間達到10ms時,就做動態擴展。這些也是預定的條件。

關於這一點,在我的工作經歷中,經常看到有性能測試工程師,對軟硬件資源、測試數據和執行策略分不清楚,甚至都不明白爲什麼要幾分鐘加幾個線程。在這種情況之下,就不能指望這個場景是有效的了。

性能測試中要有場景

可以說,“性能場景”這個詞在性能測試中佔據着舉足輕重的地位,只是我們很多人都不理解“場景”應該如何定義。場景來源於英文的scenario,對性能場景中的“場景”比較正宗的描述是:在既定的環境(包括動態擴展等策略)、既定的數據(包括場景執行中的數據變化)、既定的執行策略、既定的監控之下,執行性能腳本,同時觀察系統各層級的性能狀態參數變化,並實時判斷分析場景是否符合預期。

這纔是真正的場景全貌。

性能場景也要有分類,在我有限的工作經驗中,性能場景從來都沒有超出過這幾個分類。

  1. 基準性能場景:這裏要做的是單交易的容量,爲混合容量做準備(不要跟我說上幾個線程跑三五遍腳本叫基準測試,在我看來,那只是場景執行之前的預執行,用來確定有沒有基本的腳本和場景設計問題,不能稱之爲一個分類)。
  2. 容量性能場景:這一環節必然是最核心的性能執行部分。根據業務複雜度的不同,這部分的場景會設計出很多個,在概念部分就不細展開了,我會在後面的文章中詳細說明。
  3. 穩定性性能場景:穩定性測試必然是性能場景的一個分類。只是現在在實際的項目中,穩定性測試基本沒和生產一致過。在穩定性測試中,顯然最核心的元素是時間(業務模型已經在容量場景中確定了),而時間的設置應該來自於運維週期,而不是來自於老闆、產品和架構等這些人的心理安全感。
  4. 異常性能場景:要做異常性能場景,前提就是要有壓力。在壓力流量之下,模擬異常。這個異常的定義是很寬泛的,在下一篇文章裏,我們再細說。

很多性能測試工程師,都把場景叫成了測試用例。如果只是叫法不同,我覺得倒是可以接受,關鍵是內容也出現了很大的偏差,這個偏差就是,把用例限定在了描述測試腳本和測試數據上,並沒有描述需要實時的判斷和動態的分析。這就嚴重影響了下一個概念:性能結果。

性能測試中要有分析調優

一直以來,需不需要在性能測試項目中調優,或者說是不是性能測試工程師做調優,人們有不同的爭論。

從性能市場的整體狀態來看,在性能測試工程師中,可以做瓶頸判斷、性能分析、優化的人並不多,所以很多其他職位上的人對性能測試的定位也就是性能驗證,並不包括調優的部分。於是有很多性能項目都定義在一兩週之內。這類項目基本上也就是個性能驗證,並不能稱之爲完整的性能項目。而加入了調優部分之後,性能項目就會變得複雜。對於大部分團隊來說,分析瓶頸都可能需要很長時間,這裏會涉及到相關性分析、趨勢分析、證據鏈查找等等手段。

所以,就要不要進行調優,我做了如下劃分。

對性能項目分爲如下幾類。

  1. 新系統性能測試類:這樣的項目一般都會要求測試出系統的最大容量,不然上線心裏沒底。
  2. 舊系統新版本性能測試類:這樣的項目一般都是和舊版本對比,只要性能不下降就可以根據歷史數據推算容量,對調優要求一般都不大。
  3. 新系統性能測試優化類:這類的系統不僅要測試出最大容量,還要求調優到最好。

對性能團隊的職責定位有如下幾種。

  1. 性能驗證:針對給定的指標,只做性能驗證。第三方測試機構基本上都是這樣做的。
  2. 性能測試:針對給定的系統,做全面的性能測試,可以得到系統最大容量,但不涉及到調優。
  3. 性能測試+分析調優:針對給定的系統,做全面的性能測試,同時將系統調優到最優狀態。

當只能做性能驗證的團隊遇到舊系統新版本性能測試類和新系統性能測試優化類項目,那就會很喫力,這樣的團隊只能做新系統性能測試類項目。

當做性能測試的團隊,遇到需要新系統性能測試優化類項目,照樣很喫力。這樣的團隊能做前兩種項目。

只有第三個團隊才能做第三種項目。

性能測試肯定要有結果報告

性能結果如何來定義呢?有了前面監控的定義,有了場景執行的過程,產生的數據就要整理到結果報告中了。這個文檔工作也是很重要的,是體現性能團隊是否專業的一個重要方面。並不是整理一個Word,美化一下格式就可以了。測試報告是需要彙報或者歸檔的。

如果是內部項目,測試報告可能就是一個表格,發個郵件就完整了,另外歸檔也是必須的。而對一些有甲乙方的項目,就需要彙報了。

那麼,如何彙報呢?

我們要知道,大部分老闆或者上司關心的是測試的結果,而不是用了多少人,花了多少時間這些沒有意義的數字。我們更應該在報告中寫上調優前後的TPS、響應時間以及資源對比圖。

有了上面的的解析,相信你對性能測試的定義有了明確的感覺了。這個定義其實就是描述了性能測試中要做的事情。

當然,也許會有人跳出來說,你這個說得太重了,不夠敏捷。現在不都用DevOps了嗎?還要按這個流程來走一遍嗎?

顯然有這種說法的人,沒有理解我要說的主旨。以上的內容是針對一個完整的項目,或系統或公司的系統演進。對於一些半路就跟着版本和新需求一輪輪迭代做下去的人的處境會不同,因爲這樣的人只看到了當前的部分,而不是整個過程。

並且這個過程也是不斷在迭代演進的。

不管是敏捷開發過程還是DevOps,你可以一條條去仔細分析下項目中的各個環節(我說的是整個項目從無到有),都不會跳出以上定義,如果有的話,請隨時聯繫我,我好改定義。:)

通過圖示最後總結一下性能測試的概念:

圖片

有了這個圖示之後,就比較清晰了。

所以,前面所說的壓力測試、容量測試、負載測試等等,在實際的項目實施過程中,都不具備全局的指導價值。我個人認爲,你應該在性能領域中拋棄這些看似非常有道理實則毫無價值的概念。

性能場景TPS和響應時間

前面我們說了性能要有場景,也說了性能場景要有基準性能場景、容量性能場景、穩定性性能場景、異常性能場景。下面我將對前面說到的概念進行一一對應。

學習性能的人,一定看吐過一張圖,現在讓你再吐一次。如下:

圖片

在這個圖中,定義了三條曲線、三個區域、兩個點以及三個狀態描述。

  1. 三條曲線:吞吐量的曲線(紫色)、利用率(綠色)、響應時間曲線(深藍色)。
  2. 三個區域:輕負載區(Light Load)、重負載區(Heavy Load)、塌陷區(Buckle Zone)。
  3. 兩個點:最優併發用戶數(The Optimum Number of Concurrent Users)、最大併發用戶數(The Maximum Number of Concurrent Users)。
  4. 三個狀態描述:資源飽和(Resource Saturated)、吞吐下降(Throughput Falling)、用戶受影響(End Users Effected)。

我在很多地方,都看到了對這張圖的引用。應該說,做爲一個示意圖,它真的非常經典,的確描述出了一個基本的狀態。但是,示意圖也只能用來做示意圖,在具體的項目中,我們仍然要有自己明確的判斷。

我們要知道,這個圖中有一些地方可能與實際存在誤差。

首先,很多時候,重負載區的資源飽和,和TPS達到最大值之間都不是在同樣的併發用戶數之下的。比如說,當 CPU 資源使用率達到 100% 之後,隨着壓力的增加,隊列慢慢變長,響應時間增加,但是由於用戶數增加的幅度大於響應時間增加的幅度之前,TPS 仍然會增加,也就是說資源使用率達到飽和之後還有一段時間TPS纔會達到上限。

大部分情況下,響應時間的曲線都不會像圖中畫得這樣陡峭,並且也不一定是在塌陷區突然上升,更可能的是在重負載區突然上升。

另外,吞吐量曲線不一定會出現下降的情況,在有些控制較好的系統中會維持水平。曾經在一個項目中,因爲TPS維持水平,並且用戶數和響應時間一直都在增加,由於響應時間太快,一直沒有超時。我跟我團隊那個做壓力的兄弟爭論了三個小時,我告訴他接着壓下去已經沒有意義,就是在等超時而已。他倔強地說,由於沒有報錯,時間還在可控範圍,所以要一直加下去。關於這一點爭論,我在後續的文章中可能還會提及。

最優併發數這個點,通常只是一種感覺,並沒有絕對的數據用來證明。在生產運維的過程中,其實我們大部分人都會更爲謹慎,不會定這個點爲最優併發,而是更靠前一些。

最大併發數這個點,就完全沒有道理了,性能都已經衰減了,最大併發數肯定是在更前的位置呀。這裏就涉及到了一個誤區,壓力工具中的最大用戶數或線程數和TPS之間的關係。在具體的項目實施中,有經驗的性能測試人員,都會更關心服務端能處理的請求數即TPS,而不是壓力工具中的線程數。

這張圖沒有考慮到鎖或線程等配置不合理的場景,而這類場景又比較常見。也就是我們說的,TPS上不去,資源用不上。所以這個圖默認了一個前提,只要線程能用得上,資源就會蹭蹭往上漲。

這張圖呢,本來只是一個示意,用以說明一些關係。但是後來在性能行業中,有很多沒有完全理解此圖的人將它做爲很有道理的“典範”給一些人講,從而引起了越來越多的誤解。

此圖最早的出處是2005年Quest Software的一個PSO Consultant寫的一個白皮書 《Performance Testing Methodology》。在18頁論述了這張圖,原文摘錄一段如下:

You can see that as user load increases, response time increases slowly and resource utilization increases almost linearly. This is because the more work you are asking your application to do, the more resources it needs. Once the resource utilization is close to 100 percent, however, an interesting thing happens – response degrades with an exponential curve. This point in the capacity assessment is referred to as the saturation point. The saturation point is the point where all performance criteria are abandoned and utter panic ensues. Your goal in performing a capacity assessment is to ensure that you know where this point is and that you will never reach it. You will tune the system or add additional hardware well before this load occurs.

按照這段描述,這個人只是隨着感覺在描述一種現象,除此無它。比如說,The saturation point is the point where all performance criteria are abandoned and utter panic ensues.在我的工作經驗中,其實在saturation point之前,性能指標就已經可以顯示出問題了,並且已經非常panic了,而我們之所以接着再加壓力是爲了讓指標顯示得更爲明顯,以便做出正確的判斷。而調優實際上是控制系統在飽和點之前,這裏有一個水位的問題,控制容量到什麼樣的水位纔是性能測試與分析的目標。

我們簡化出另一個圖形,以說明更直接一點的關係。如下所示:

圖片

上圖中藍線表示TPS,黃色表示響應時間。

在TPS增加的過程中,響應時間一開始會處在較低的狀態,也就是在A點之前。接着響應時間開始有些增加,直到業務可以承受的時間點B,這時TPS仍然有增長的空間。再接着增加壓力,達到C點時,達到最大TPS。我們再接着增加壓力,響應時間接着增加,但TPS會有下降(請注意,這裏並不是必然的,有些系統在隊列上處理得很好,會保持穩定的TPS,然後多出來的請求都被友好拒絕)。

最後,響應時間過長,達到了超時的程度。

在我的工作中,這樣的邏輯關係更符合真實的場景。我不希望在這個關係中描述資源的情況,因爲會讓人感覺太亂了。

爲什麼要把上面描述得如此精細?這是有些人將第一張圖中的Light load對應爲性能測試,Heavy Load對應爲負載測試,Buckle Zone對應爲壓力測試……還有很多的對應關係。

事實上,這是不合理的。

下面我將用場景的定義來替換這些混亂的概念。

爲什麼我要如此劃分?因爲在具體場景的操作層面,只有場景中的配置纔是具體可操作的。而通常大家認爲的性能測試、負載測試、壓力測試在操作的層面,只有壓力工具中線程數的區別,其他的都在資源分析的層面,而分析在很多人的眼中,都不算測試。

拿配置測試和遞增測試舉例吧。

在性能中,我們有非常多的配置,像JVM參數、OS參數、DB參數、網絡參數、容器參數等等。如果我們把測試這些配置參數,稱爲“配置測試”,我覺得未免過於狹隘了。因爲對於配置參數來說,這只是做一個簡單的變更,而性能場景其實沒有任何變化呀。配置更改前後,會用同樣的性能場景來判斷效果,最多再增加一些前端的壓力,實際的場景並沒有任何變化,所以,我覺得它不配做爲一個單獨的分類。

再比如遞增測試,在性能中,基準性能場景也好,容量性能場景也好,哪個是不需要遞增的呢?我知道現在市場上經常有測試工程師,直接就上了幾百幾千線程做壓力(請你不要告訴我這是個正常的場景,鑑於我的精神有限,承受不了這樣的壓力)。除了秒殺場景,同時上所有線程的場景,我還沒有見到過。在一般的性能場景中,遞增都是必不可少的過程。同時,遞增的過程,也要是連續的,而不是100線程、200線程、300線程這樣斷開執行場景,這樣是不合理的。關於這一點,我們將在很多地方着重強調。所以我覺得遞增也不配做一個單獨的分類。

其他的概念,就不一一批駁了。其實在性能測試中,在實際的項目實施中,我們並不需要這麼多概念,這些雜七雜八的概念也並沒有對性能測試領域的發展起到什麼推進作用。要說雲計算、AI、大數據這些概念,它們本身在引導着一個方向。

而性能測試中被定爲“測試”,本身就處在軟件生存週期的弱勢環節,當前的市場發展也並不好。還被這些概念衝亂了本來應該有的邏輯的思路,實在是得不償失。

理解TPS、QPS、RT、吞吐量這些性能指標

通常我們都從兩個層面定義性能場景的需求指標:業務指標和技術指標。

這兩個層面需要有映射關係,技術指標不能脫離業務指標。一旦脫離,你會發現你能回答“一個系統在多少響應時間之下能支持多少TPS”這樣的問題,但是回答不了“業務狀態是什麼”的問題。

舉例來說,如果一個系統要支持1000萬人在線,可能你能測試出來的結果是系統能支持1萬TPS,可是如果問你,1000萬人在線會不會有問題?這估計就很難回答了。

我在這裏畫一張示意圖以便你理解業務指標和性能指標之間的關係。

圖片

這個示意顯然不夠詳細,但也能說明關係了。所有的技術指標都是在有業務場景的前提下制定的,而技術指標和業務指標之間也要有詳細的換算過程。這樣一來,技術指標就不會是一塊飛地。同時,在回答了技術指標是否滿足的同時,也能回答是否可以滿足業務指標。

有了這樣的關聯關係,下面我們看一下性能測試行業常用的性能指標表示法。

我將現在網上能看到的性能指標做了羅列,其中不包括資源的指標。因爲資源類的比較具體,並且理解誤差並不大,但業務類的差別就比較大了。

對這些性能指標都有哪些誤解

我記得我還年輕的時候,還沒有QPS、RPS、CPS這樣的概念,只有TPS。那個時候,天總是那麼藍,時間總是那麼慢,“你鎖了人家就懂了”。

QPS一開始是用來描述MySQL中SQL每秒執行數Query Per Second,所有的SQL都被稱爲Query。後來,由於一些文章的轉來轉去,QPS被慢慢地移到了壓力工具中,用來描述吞吐量,於是這裏就有些誤解,QPS和TPS到底是什麼關係呢?

RPS指的是每秒請求數。這個概念字面意思倒是容易理解,但是有個容易誤解的地方就是,它指的到底是哪個層面的Request?如果說HTTP Request,那麼和Hits Per Second又有什麼關係呢?

HPS,這也是個在字面意思上容易理解的概念。只是Hit是什麼?有人將它和HTTP Request等價,有人將它和用戶點擊次數等價。

CPS,用的人倒是比較少,在性能行業中引起的誤解範圍並不大。同時還有喜歡用CPM(Calls Per Minute,每分鐘調用數)的。這兩個指標通常用來描述Service層的單位時間內的被其他服務調用的次數,這也是爲什麼在性能行業中誤解不大的原因,因爲性能測試的人看Service層東西的次數並不多。

爲了區分這些概念,我們先說一下TPS(Transactions Per Second)。我們都知道TPS是性能領域中一個關鍵的性能指標概念,它用來描述每秒事務數。我們也知道TPS在不同的行業、不同的業務中定義的粒度都是不同的。所以不管你在哪裏用TPS,一定要有一個前提,就是 所有相關的人都要知道你的T是如何定義的

經常有人問,TPS應該如何定義?這個實在是沒有具體的“法律規定”,那就意味着,你想怎麼定就怎麼定。

通常情況下,我們會根據場景的目的來定義TPS的粒度。如果是接口層性能測試,T可以直接定義爲接口級;如果業務級性能測試,T可以直接定義爲每個業務步驟和完整的業務流。

我們用一個示意圖來說明一下。

圖片

如果我們要單獨測試接口1、2、3,那T就是接口級的;如果我們要從用戶的角度來下一個訂單,那1、2、3應該在一個T中,這就是業務級的了。

當然,這時我們還要分析系統是如何設計的。通常情況下,積分我們都會異步,而庫存不能異步哇。所以這個業務,你可以看成只有1、2兩個接口,但是在做這樣的業務級壓力時,3接口也是必須要監控分析的。

所以,性能中TPS中T的定義取決於場景的目標和T的作用。一般我們都會這樣來定事務。

  • 接口級腳本:

    ——事務start(接口1)

    接口1腳本

    ——事務end(接口1)

    ——事務start(接口2)

    接口2腳本

    ——事務end(接口2)

    ——事務start(接口3)

    接口3腳本

    ——事務end(接口3)

  • 業務級接口層腳本(就是用接口拼接出一個完整的業務流):

    ——事務start(業務A)

    接口1腳本 - 接口2(同步調用)

    接口1腳本 - 接口3(異步調用)

    ——事務end(業務A)

  • 用戶級腳本

    ——事務start(業務A)

    點擊0 - 接口1腳本 - 接口2(同步調用)

    點擊0 - 接口1腳本 - 接口3(異步調用)

    ——事務end(業務A)

你要創建什麼級別的事務,完全取決於測試的目的是什麼。

一般情況下,我們會按從上到下的順序一一地來測試,這樣路徑清晰地執行是容易定位問題的。

重新理解那些性能指標概念

搞清楚了TPS的T是什麼,下面就要說什麼是TPS了。字面意思非常容易理解,就是: 每秒事務數

在性能測試過程中,TPS之所以重要,是因爲它可以反應出一個系統的處理能力。我在很多場景中都說過,事務就是統計了一段腳本的執行時間,並沒有什麼特別的含義。而現在又多加了其他的幾個概念。

首先是QPS,如果它描述的是數據庫中的Query Per Second,從上面的示意圖中來看,其實描述的是服務後面接的數據庫中SQL的每秒執行條數。如果描述的是前端的每秒查詢數,那就不包括插入、更新、刪除操作了。顯然這樣的指標用來描述系統整體的性能是不夠全面的。所以不建議用QPS來描述系統整體的性能,以免產生誤解。

RPS(Request per second),每秒請求數。看似簡單的理解,但是對於請求數來說,要看是在哪個層面看到的請求,因爲請求這個詞,實在是太泛了。我們把上面的圖做一點點變化來描述一下請求數。

圖片

如果一個用戶點擊了一次,發出來3個HTTP Request,調用了2次訂單服務,調用了2次庫存服務,調用了1次積分服務,那麼這個Request該如何計算?如果你是算GDP的專家,我覺得可能會是:3+2+2+1=8(次)。而在具體的項目中,我們會單獨描述每個服務,以便做性能統計。如果要描述整體,最多算是有3個RPS。如果從HTTP協議的角度去理解,那麼HTTP Request算是一個比較準確的描述了,但它本身的定義並沒有包含業務。如果賦予它業務的含義,那麼用它來描述性能也是可以的。

HPS(Hits Per Second),每秒點擊數。Hit一般在性能測試中,都用來描述HTTP Request。但是,也有一些人用它描述真正的客戶在界面上的點擊次數。關於這一點,就只有在具體的項目中才能規定得具體一些。當它描述HTTP Request時,如果RPS也在描述HTTP Request,那這兩個概念就完全一樣了。

CPS/CPM:Calls Per Second/ Calls Per Minutes,每秒/每分鐘調用次數。這個描述在接口級是經常用到的,比如說上面的訂單服務。顯然一次客戶界面上的點擊調用兩次。這個比較容易理解。但是,在操作系統級,我們也經常會聽到系統調用用call來形容,比如說用strace時,你就會看見Calls這樣的列名。

這些概念本身並沒有問題,但是當上面的概念都用來描述一個系統的性能能力的時候,就混亂了。對於這種情況,我覺得有幾種處理方式:

  1. 用一個概念統一起來。我覺得直接用TPS就行了,其他的都在各層面加上限制條件來描述。比如說,接口調用1000 Calls/s,這樣不會引起混淆。
  2. 在團隊中定義清楚術語的使用層級。
  3. 如果沒有定義使用層級,那隻能在說某個概念的時候,加上相應的背景條件。

所以,當你和同事在溝通性能指標用哪些概念時,應該描述得更具體一些。在一個團隊中,應該先有這些術語統一的定義,再來說性能指標是否滿足。

響應時間RT

在性能中,還有一個重要的概念就是響應時間(Response Time)。這個比較容易理解。我們接着用這張示意圖說明:

圖片

RT = T2-T1。計算方式非常直接簡單。但是,我們要知道,這個時間包括了後面一連串的鏈路。

響應時間的概念簡單至極,但是,響應時間的定位就複雜了。

性能測試工具都會記錄響應時間,但是,都不會給出後端鏈路到底哪裏慢。經常有人問問題就直接說,我的響應時間很慢。問題在哪呢?在這種情況下,只能回答:不知道。

因爲我們要先畫架構圖,看請求鏈路,再一層層找下去。比如說這樣:

圖片

在所有服務的進出口上都做記錄,然後計算結果就行了。在做網關、總線這樣的系統時,基本上都會考慮這個功能。

而現在,隨着技術的發展,鏈路監控工具和一些Metrics的使用,讓這個需求變得簡單了不少。比如說這樣的展示:

圖片

它很直觀地顯示了,在一個請求鏈路上,每個節點消耗的時間和請求的持續時間。

我順便在這裏說一下調優在當前性能項目中的狀態。

對於響應時間來說,時間的拆分定位是性能瓶頸定位分析中非常重要的一節。但是請注意,這個環節並不是性能測試工程師的最後環節。

在工作中,我經常看到有很多性能測試工程師連時間拆分都不做,只報一個壓力工具中看到的響應時間,就給一個通過不通過的結論,絲毫沒有定位。

另外,有一些性能測試工程師,倒是用各種手段分析了時間的消耗點,但是也覺得自己的工作就此結束了,而不做根本原因的分析或協調其他團隊來分析。

當然在不同的企業裏,做分析的角色和要求各不相同,所以也要根據實際的企業現狀來說。

在我的觀點中,性能只測不調,那就是性能驗證的工作,稱不上是完整的性能項目。第三方性能測試的機構可以這樣做,但是在一個企業內部這樣做的話,性能團隊的價值肯定就大打折扣了。

但是現在有很多人都不把性能調優做爲性能團隊的工作,主要原因有幾點:

  1. 性能測試團隊的人能力有限做不到;
  2. 性能調優代價高,耗時長,不值得做。

在我帶的性能項目中,基本上調優的工作都是我的團隊主導的。性能團隊當然不可能完全沒有技術弱點,所以在很多時候都是協調其他團隊的人一起來分析瓶頸點。那爲什麼是我的團隊來主導這個分析的過程呢?

因爲每個技術人員對性能瓶頸的定義並不相同,如果不細化到具體的計數器的值是多少纔有問題,有誤解的可能性就很大。

曾經我在某零售業大廠做性能諮詢的時候,一房間的技術人員,開發、運維、DBA都有,結果性能瓶頸出現了,所有人都說自己的部分是沒問題的。於是我一個個問他們是如何判斷的,判斷的是哪個計數器,值又是多少。結果發現很多人對瓶頸的判斷都和我想像的不一樣。

舉例來說,DB的CPU使用率達到90%以上,DBA會覺得沒有問題,因爲都是業務的SQL,並不是DB本身有問題。開發覺得SQL執行時間慢是因爲DB有問題,而不是自己寫的有問題,因爲業務邏輯並沒有錯,有問題的點應該是DB上索引不合理、配置不合理。

你看,同樣的問題,每個人的看法都有區別。當然也不能排除有些人就是想推諉責任。

這時怎麼辦呢?如果你可以把執行計劃拿出來,告訴大家,這裏應該創建索引,而那裏應該修改業務條件,這時就具體了。

壓力工具中的線程數和用戶數與TPS

總是有很多人在併發線程數和TPS之間遊蕩,搞不清兩者的關係與區別。這兩個概念混淆的點就是,好像線程是真實的用戶一樣,那併發的線程是多少就描述出了多少真實的用戶。

但是做性能的都會知道,併發線程數在沒有模擬真實用戶操作的情況下,和真實的用戶操作差別非常遠。

在LoadRunner還比較紅火的時候,Mercury提出一個BTO的概念,就是業務科技優化。在LoadRunner中也提出”思考時間“的概念,其實在其他的性能工具中是沒有“思考時間”這個詞的。這個詞的提出就是爲了性能工具模擬真實用戶。

但是隨着性能測試的地位不斷下降,以及一些概念和名詞不斷地被以訛傳訛,導致現在很多人都沒有明白壓力工具中的線程數和用戶以及TPS之間是怎樣的關係。同樣,我們先畫一個示意圖來說明一下。

圖片

這裏先說明一個前提,上面的一個框中有四個箭頭,每個都代表着相同的事務。

在說這個圖之前,我們要先說明“併發”這個概念是靠什麼數據來承載的。

在上面的內容中,我們說了好多的指標,但併發是需要具體的指標來承載的。你可以說,我的併發是1000TPS,或者1000RPS,或者1000HPS,這都隨便你去定義。但是在一個具體的項目中,當你說到併發1000這樣沒有單位的詞時,一定要讓大家都能理解這是什麼。

在上面這張示意圖中,其實壓力工具是4個併發線程,由於每個線程都可以在一秒內完成4個事務,所以總的TPS是16。這非常容易理解吧。而在大部分非技術人的腦子裏,這樣的場景就是併發數是4,而不是16。

要想解釋清楚這個非常困難,我的做法就是,直接告訴別人併發是16就好了,不用關心4個線程這件事。這在我所有項目中幾乎都是一樣的,一直也沒有什麼誤解。

那麼用戶數怎麼來定義呢?涉及到用戶就會比較麻煩一點。因爲用戶有了業務含義,所以有些人認爲一個系統如果有1萬個用戶在線,那就應該測試1萬的併發線程,這種邏輯實在是不技術。通常,我們會對在線的用戶做併發度的分析,在很多業務中,併發度都會低於5%,甚至低於1%。

拿5%來計算,就是10000用戶x5%=500(用戶級TPS),注意哦,這裏是TPS,而不是併發線程數。如果這時響應時間是100ms,那顯然併發線程數是500TPS/(1000ms/100ms)=50(併發線程)。

通過這樣簡單的計算邏輯,我們就可以看出來用戶數、線程數和TPS之間的關係了。

圖片

但是!響應時間肯定不會一直都是100ms的嘛。所以通常情況下,上面的這個比例都不會固定,而是隨着併發線程數的增加,會出現趨勢上的關係。

所以,在性能分析中,我一直在強調着一個詞: 趨勢!

業務模型的28原則是個什麼鬼?

我看到有些文章中寫性能測試要按28原則來計算併發用戶數。大概的意思就是,如果一天有1000萬的用戶在使用,系統如果開10個小時的話,在計算併發用戶數的時候,就用2小時來計算,即1000萬用戶在2小時內完成業務。

我要說的是,這個邏輯在一個特定的業務系統中是沒有任何價值的。因爲每個系統的併發度都由業務來確定,而不是靠這樣的所謂的定律來支配着業務。

如果我們做了大量的樣本數據分析,最後確實得出了28的比例,我覺得那也是可以的。但是如果什麼數據都沒有分析,直接使用28比例來做評估和計算,那就跟耍流氓沒有區別。

業務模型應該如何得到呢?這裏有兩種方式是比較合理的:

  1. 根據生產環境的統計信息做業務比例的統計,然後設定到壓力工具中。有很多不能在線上直接做壓力測試的系統,都通過這種方式獲取業務模型。
  2. 直接在生產環境中做流量複製的方式或壓力工具直接對生產環境發起壓力的方式做壓力測試。這種方式被很多人稱爲全鏈路壓測。其實在生產中做壓力測試的方式,最重要的工作不是技術,而是組織協調能力。相信參與過的人都能體會這句話的重量。

響應時間的258原則合理嗎?

對於響應時間,有很多人還在說着258或2510響應時間是業內的通用標準。然後我問他們這個標準的出處在哪裏?誰寫的?背景是什麼?幾乎沒有人知道。真是不能想像,一個誰都不知道出處的原則居然會有那麼大的傳播範圍,就像謠言一樣,出來之後,再也找不到源頭。

其實這是在80年代的時候,英國一家IT媒體對音樂緩衝服務做的一次調查。在那個年代,得到的結果是,2秒客戶滿意度不錯;5秒滿意度就下降了,但還有利潤;8秒時,就沒有利潤了。於是他們就把這個統計數據公佈了出來,這樣就出現了258 principle,翻譯成中文之後,它就像一個萬年不變的定理,深深影響着很多人。

距離這個統計結果的出現,已經過去快40年了,IT發展的都能上天了,這個時間現在已經完全不適用了。所以,以後出去別再提258/2510響應時間原則這樣的話了,太不專業。

那麼響應時間如何設計比較合理呢?這裏有兩種思路推薦給你。

  1. 同行業的對比數據。
  2. 找到使用系統的樣本用戶(越多越好),對他們做統計,將結果拿出來,就是最有效的響應時間的制定標準。

性能指標的計算方式

我們在網上經常可以看到有人引用這幾個公式。

公式(1):

併發用戶數計算的通用公式:

其中C是平均的併發用戶數;n是login session的數量;L是login session的平均長度;T指考察的時間段長度。

公式(2):

併發用戶數峯值: 

C’指併發用戶數的峯值,C就是公式(1)中得到的平均的併發用戶數。該公式是假設用戶的login session產生符合泊松分佈而估算得到的。

仔細搜索之後發現會發現這兩個公式的出處是2004年一個叫Eric Man Wong的人寫的一篇名叫《Method for Estimating the Number of Concurrent Users》的文章。中英文我都反覆看到很多篇。同時也會網上看到有些文章中把這個文章描述成“業界公認”的計算方法。

在原文中,有幾個地方的問題。

  1. C並不是併發用戶,而是在線用戶。
  2. 這兩個公式做了很多的假設條件,比如說符合泊松分佈什麼的。爲什麼說這個假設有問題?我們都知道泊松分佈是一個鐘型分佈,它分析的是一個系統在全週期中的整體狀態。
  3. 如果要讓它在實際的項目中得到實用,還需要有大量的統計數據做樣本,代入計算公式才能驗證它的可信度。
  4. 峯值的計算,我就不說了,我覺得如果你是做性能的,應該一看就知道這個比例不符合大部分真實系統的邏輯。
  5. 有些人把這兩個公式和Little定律做比較。我要說Little定律是最基礎的排隊論定律,並且這個定律只說明瞭:系統中物體的平均數量等於物體到達系統的平均速率和物體在系統中停留的平均時間的乘積。我覺得這句話,就跟秦腔中的”出門來只覺得脊背朝後“是一樣一樣的。

有人說應該如何來做系統容量的預估呢。我們現在很多系統的預估都是在一定的假設條件之下的,之所以是預估,說明系統還不在,或者還沒達到那樣的量。在這種情況下,我們可以根據現有的數據,做統計分析、做排隊論模型,進而推導以後的系統容量。

但是我們所有做性能的人都應該知道,系統的容量是演進來的,而不是光憑預估就可以得出準確數值的。

總結

在性能測試的概念中,性能指標、性能模型、性能場景、性能監控、性能實施、性能報告,這些既是概念中的關鍵詞,也可以說是性能測試的方法和流程。

而這些概念我們在實際的工作中,都是非常重要的。因爲它們要抹平溝通的誤解。讓不同層級,不同角色的人,可以在同樣的知識背景下溝通,也可以讓做事情的人有清晰的邏輯思路,同時對同行間的交流,也有正向的促進作用。

性能測試策略、性能測試場景、性能測試指標,這些關鍵的概念在性能測試中深深地影響着很多人。我們簡化它的邏輯,只需要記住幾個關鍵字就可以,其他的都不必使用。

  1. 性能測試概念中:性能指標、性能模型、性能場景、性能監控、性能實施、性能報告。

  2. 性能場景中:基準場景、容量場景、穩定性場景、異常場景。

  3. 性能指標中:TPS、RT。 (記住T的定義是根據不同的目標來的)

在具體的性能項目中,性能場景是一個非常核心的概念。因爲它會包括壓力發起策略、業務模型、監控模型、性能數據(性能中的數據,我一直都不把它稱之爲模型,因爲在數據層面,測試並沒有做過什麼抽象的動作,只是使用)、軟硬件環境、分析模型等。

 

作者|頂尖架構師棧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章