
題目:你正在做的性能測試不是你想象中的樣子
1996年LR 4.0版本釋出,将性能測試專業理論工具化、産品化,這也直接影響後20多年至今性能測試領域的理論基礎。但是LR是一個商業化産品,價格昂貴,1998年底開源社群Jmeter 1.0釋出上線,性能測試逐漸蓬勃發展起來了。
Loadrunner、Jmeter引領了性能測試領域的一個時代,功能強大、腳本化、擴充性強,将性能測試标準化、專業化,後續幾乎所有性能測試工具或者商業化産品均唯其馬首是瞻。本文就性能測試做了一個純YY的“實踐”(真的隻是純理論分析!),有一些不一樣的思路跟大家一起探讨下,望輕踩。
1. 前言:并發、RPS和RT
接觸性能測試的同學要了解的概念非常多,在正文之前先跟大家就幾個核心名額統一下口徑:
- 并發使用者、并發、VU:一般用來表示虛拟使用者(Virutal User,簡稱VU),對應到Jmeter的線程組線程,對應到Loadrunner的并發Concurrency,在本文均為同一意思。
- 每秒發送請求數、RPS:指用戶端每秒發出的請求數,有些地方也叫做QPS,本文不單獨讨論“事務”,是以可以近似對應到Loadrunner的TPS(Transaction Per Second, 每秒事務數),本文統一稱為RPS。
- 響應時間、RT:從發起請求到完全接收到應答的時間消耗。
根據“Little定律”,在平衡狀态下,我們可以等價認為并發、RPS和RT之間的關系可以概括為
并發數 = RPS * 響應時間
偷懶的話,可以把它當成性能測試領域的“乘法口訣”,直接背下來吧,他會幫助你快速了解很多問題;如果想深入了解具體的原理,可以拜讀下Eric Man Wong 在2004年發表了名為《Method for Estimating the Number of Concurrent Users》的文章,這兩者是等價的。
2. 100勞工的問題
如果你還不了解“RT對于并發模式的性能測試的影響”,或者還存在一些疑惑,強烈建議讀完本章;如果不想了解細節,可以選擇直接跳到本章末尾看結論;如果已經充分了解了,可以直接跳過本章。
先從一個大家相對熟知的例子開始,假設有這麼一條生産箱子的流水線,安排了100個勞工,條件如下:
- 100個勞工的身體素質一模一樣, 是以可以近似的認為工作效率隻與工作的複雜度有關;
- 這個流水線有3份工作(如下圖所示的節點A、節點B和節點C),所有勞工都可以勝任;
- 節點A勞工包裝箱子平均耗時 RT1=0.5s(秒),節點B勞工包裝箱子平均耗時 RT2=3s(秒),節點C勞工包裝箱子平均耗時 RT3=1.5s(秒)
- 同一個箱子必須按照節點A、節點B、節點C的順序被包裝。
問:節點A、節點B、節點C分别安排多少勞工X、Y、Z可以讓這個流水線達到最大的産能,并且求得流水線的最大産能T/s?如下圖所示。
圖1
在平衡狀态下,我們從宏觀的視角來分析下,整條流水線包裝完一個箱子的總耗時=(0.5+3+1.5)s,那麼我們可以很輕易地得到流水線的産能:
流水線的産能 T = 100 / (0.5 + 3 + 1.5) = 20 /s
可能很多人有疑問,“什麼是平衡狀态?”,這個可以這麼了解,為了保證所有勞工都可以達到最大的工作效率,主管會非常睿智的調配各個節點之間的勞工配置設定直到“所有勞工都有事可做,也不會存在勞工忙不過來”,那麼從微觀的角度去看,如果節點之間的産能不一緻,有些節點就會出現箱子等待被處理,有些節點的勞工等待箱子的情況。是以,我們可以得到這樣的結論:在平衡狀态下,所有節點産能肯定是一緻的:
T(A) = T(B) = T(C) = T = 20 /s
進而,根據little定律,我們可以推算出來,各個節點的人員(vu)配置設定了:
X = T(A) RT1 = 20 0.5 = 10
Y = T(B) RT2 = 20 3 = 60
Z = T(C) RT3 = 20 1.5 = 30
下面這張Jmeter的圖,相信大家可以輕易地跟前面的自理找到對照關系,這裡不再贅述:
産能 = RPS
勞工 = 并發
完成平均時間RT = 響應時間、RT(rt)
圖2
綜上所述,我們可以得出兩個結論:
- 在平衡狀态下,所有節點的RPS必然一樣;
- 在平衡狀态下,任意節點的RT都會影響整體RPS,進而會影響并發在節點之間的配置設定關系。
為了描述友善,我們将節點A、節點B和節點C組成的“100人的流水線”叫做“串聯鍊路”。
節點A的RPS = 節點B的RPS = ... = 串聯鍊路RPS
串聯鍊路RPS = 并發數 / (RT1 + RT2 + ... )
節點N的并發數 = RTn 節點N的RPS = RTn 串聯鍊路RPS
3. 你确定考慮全面了嗎?
控制并發是目前最為普遍被使用到的壓測模式,打個比方,有一個網站在下周一10:00預估有10w人同時通路,那麼為了保障網站,很自然的想到使用10w個并發來壓測下整個網站的接口,對應到JMeter即為設定線程組的線程數,對應到LoadRunner設定VU(Visual User)數,很容易了解。
另外,近6個月的阿裡雲PTS[1]官方資料顯示,近10000+企業使用者中,選擇并發模式與RPS模式分别占比89%與11%,并發模式占據絕對的規模優勢。
但是,如果你已經充分了解了“RT對于固定并發模式的性能測試的影響”,這裡我不禁要問一句“Emm... 你有想過類似Jmeter、LR等并發模式壓測工具拿到的結果是真實的嗎?準确嗎?”。
下面我要講一個“恐怖故事”,先來看一張相對抽象的環境結構圖。
圖3
在平衡狀态下,已知總并發VU,以及接口1、接口2、接口3的響應時間分别為RT1、RT2、RT3,通過前面的理論基礎,我們可以輕易地寫出下面的算式:
T = RPS1 = RPS2 = RPS3 = VU / (RT1 + RT2 + RT3)
接口1的并發 X = T * RT1
接口2的并發 Y = T * RT2
接口3的并發 Z = T * RT3
分析下接口的RT的構成,大緻概括為下面5部分:
- 壓測工具耗時:這個很好了解,壓測工具在發送請求之前會做參數的拼裝/替換、下載下傳應答封包、解析應答封包(斷言)等都是需要耗費時間的,一般情況下壓測工具的時間消耗會非常低,可以忽略。但是對于封包較大或者斷言較複雜的情況下,壓測工具耗時過大也會出現瓶頸;
- 網絡時間:一般來說在VPC/IDC内部的網絡消耗非常低,是以我們可以近似地認為網絡時間消耗都來源于營運商網絡。同樣,對于接口的請求和應答封包比較大的情況下,不論是營運商網絡還是内網網絡的帶寬都更容易出現瓶頸;
- 安全、鑒權、負載均衡子產品耗時:這一塊的時間消耗一般來說相對較低,受限于連接配接數、帶寬等,可能會出現配置問題,比如連接配接數上限超過預期,則會造成等待建連逾時;
- 應用業務處理耗時:一般情況下,應用業務處理耗時占據RT的百分比最高,也是我們通過優化提高吞吐量的重點區域。可能包含應用之間RPC服務調用、資料庫SQL執行、讀寫緩存、讀寫消息等。
- 第三方依賴耗時:這裡就複雜了,各種情況都有,你可以完全信賴或者完全不信賴它的穩定性。一般它的RT評估有相關SLA的要求,一般壓測實施的時候根據SLA約定的RT要求,mock掉第三方接口依賴,正式壓測的時候再一起聯壓。
更進一步,可以得出這樣的結論,在并發模式下,影響壓測結果以及應用伺服器的吞吐量的因素有:
- 壓測工具的性能
- 網絡狀态
- 接入層配置和性能
- 應用服務性能
- 第三方依賴的SLA
...
是以,出現了一種混沌狀态,可能由于壓測工具所在主控端負載變化、網絡環境變化、應用服務性能優化或者劣化等因素的幹擾,拿着相同的腳本進行了10次,每次得到的接口RPS都不一樣,伺服器端的壓力也不一樣,但是從表象來看,一切正常,但這樣的性能測試并不能真實反映任何問題,也并不能指導運維做出正确容量規劃的決策。因為影響RT的因素實在是太多太多了,任何客觀因素都直接影響測試結果的準确性。
4. 并發模式=性能瓶頸“定性”分析
在這裡,我更願意定義并發模式性能測試為一種性能瓶頸分析的定性工具,在盡量相同的條件下經過反複測試,通過分析各個接口的RT構成找到“相對的”性能瓶頸。但是大家有沒有想過,将所有接口優化到極限的性能之後,可以拍胸脯說“我們的系統已經可以抗住XXX并發使用者量的通路了”嗎?答案是否定的,原因有三:
- 不真實,主要展現在①環境不真實;②壓測(腳本)模型不真實;
- 主體錯誤,并發隻是一個誘因和觸發器,影響性能的主體是服務端的RPS;
- 并發測試的效果真實性依賴于RT,而RT的構成異常複雜。
對了,前面的分析漏了(我故意的)一個影響并發性能測試結果的非常重要的因素:思考時間(使用者在操作的時候,步驟之間使用者會停頓一段時間)。思考時間的引入會将并發的模組化的複雜度帶到幾乎不能實作的地步,因為它不像其他相對客觀的因素,它是非常主觀的。假如使用者停留的時間很長,可能是因為感興趣多看一會兒,或者頁面上有100個表單需要填寫,或者看不懂文案是啥意思正在google,或者...去沖咖啡了。
有人可能會追問“思考時間究竟要設定多少合适呢?”,我可以非常明确的說“不知道!”,如果你有時間,可以通過大資料BI分析統計學意義上的每個接口之間使用者停頓的時間,然後将它設定上,假設每個接口的思考時間總和為 S=(S1+S2+S3),那麼我們可以更新下公式:
T = RPS1 = RPS2 = RPS3 = VU / (RT1 + RT2 + RT3 + S)
可以看到,增加了思考時間之後,整體的吞吐量、所有接口的并發都下降了,因為有部分使用者在“思考”。增加“思考時間”有助于提高并發模式下性能測試的準确性,除此之外,還有一些提高并發模式的準确性的手段:
- 壓測工具地域定制、營運商定制;
- 增加條件跳轉,模拟使用者重試行為;
- 增加集合點。
這些手段你可以非常輕易的在市面上的開源或者雲測平台上找到(有些功能可能需要支付一些費用),在這裡不再一一贅述,歸根到底,可以總結為“優化接口RT使其接近真實值以提高并發模式的準确性”。
但并發模式始終都受制于“不穩定的”、“難模拟的”、“難預測的”接口RT,通過并發模式拿到指導運維進行容量規劃的結果,是要付出的代價會非常大,甚至也不能達到想要的結果。
在真實情況下,接口1、接口2、接口3的RPS是不一樣的,抛開接口異常斷言失敗不繼續調用後面的接口的情況,接口RPS關系是呈倒金字塔分布,比方說,浏覽商品(接口)了之後不一定會去下單購買(接口),因為大家一般會反複浏覽不同的商品選擇最中意的再下單,是以浏覽商品(接口)的RPS必然會比下單購買(接口)的RPS要高,使用者有放棄繼續“走下一步”的權利,但是這種情況你如果嘗試對并發的分布來模組化,是一個非常龐大且複雜工程問題,因為影響的因素實在太多了。
如下圖所示,并發壓測模式下,所有接口的RPS都是一樣的,與“實際情況”(圖右部分)大相徑庭。
圖4
受傳統性能測試思路的影響,目前有接近90%的企業使用者(資料來源于阿裡雲PTS[1] ) 将并發模式性能測試的結果作為穩定性、容量驗收的依據,是以說這是一件非常恐怖的事情。
5. 容量規劃:從定性分析到定量分析
在這裡我非常樂意跟大家分享一份來源于QA Intelligence[2]《State of Testing™ Report 2019》關于2016~2019年軟體開發模式的調查資料:
圖5
軟體開發模式占比(2019、2018、2017、2016)
資料顯示,DevOps第一次超過Waterfall(瀑布模式)成為第二位被越來越多的企業接受的開發模式,而瀑布模式等傳統開發模式有逐漸退出曆史舞台的趨勢。靈活開發和DevOps大行其道,開發、測試和運維等部門、角色之間需要有一種高效的溝通和協作手段。
想到了一句非常“膚淺”但有點道理的話,“性能問題優化之後最終都可以轉化為容量問題”,簡單地可以了解為測試同學發現了性能瓶頸,然後開發同學經過了優化,運維同學根據優化之後的系統的能力進行擴容或者縮容。瞧!這不就是開發、測試和運維完美協作的一個典型實踐嘛?
這個過程,我們叫做“容量規劃”的實施過程,重點不是容量而是規劃,如果成本不是任何問題,我們可以堆砌無限大的資源,使用者體驗會極其好,但是會造成極大的資源浪費。是以這裡說的“容量規劃”是在保證使用者體驗不受影響(穩定性)的前提下,使有限的資源的使用率最大化(成本)的方法論。打個比方,運維準備了100台機器,有5個應用,那麼“怎麼配置設定這100台機器給5個應用可以使系統既可以正常對外服務又可以使系統達到最大的吞吐量能力”就是容量規劃要解決的問題。
容量規劃的核心有一張已經用的“泛黃”的圖,大家應該一看就明白,有兩個核心名額:
- 預估的業務量級:對于單應用而言就是這個應用的RPS吞吐量峰值,這個資料一般可以來源于流量模型和曆史資料沉澱;
- 單台機器的能力值:在某一個流量模型下,單台機器系統水位達到安全水位時的RPS峰值。
圖6
上面提到一個概念叫做“流量模型”,這個流量模型你可以近似的認為就是前面圖中“實際情況”的RPS倒金字塔,他有兩個要素:
- 接口範圍;
- 每個接口的RPS。
容量規劃的目的性非常強,也就是在特定“流量模型”下,給出資源配置設定的最優解。在壓測實施的時候,壓測的主體是接口的RPS,按照流量模型進行試壓。(如果你還在想為什麼主體是RPS而不是并發的話,請在仔細閱讀前面那章。)
RPS模式壓測在容量規劃的典型應用,是并發模式無法實作的。正式因為此,我們才能将性能測試從“定性分析”轉化為“定量分析”。
阿裡在2013年建構了一整套基于線上全鍊路壓測的容量規劃體系,逐漸替代之前單應用、單接口這種低效的容量評估手段,過程也是非常曲折的。容量規劃是一個非常大的課題,本文的重點不是“容量規劃”,如果你對“智能化全鍊路容量規劃”感興趣,請留言。
6. 結尾:無意引戰
并發模式與RPS模式壓測各有各自的使用場景,并發模式更加适用于對于系統定性的分析,比如幫助定位性能瓶頸,單接口的性能基線沉澱(對比曆史性能優化or劣化);而RPS模式在對系統做定量的分析有傑出表現,比如容量規劃,全鍊路性能基線沉澱,當然也可以幫助定位性能瓶頸。并發模式的難點在于RT的準确性拟真,RPS模式的難點在于模型的準确性評估和預測,從實作難度上來說,前者相對于後者來說難度更大一些、掌控度更低一些。
當然,我無意引戰,并發模式、RPS模式、你想要的和你還沒有想到未來想要的都可以在阿裡雲PTS[1]上找到。
參考文檔
[1] 阿裡雲PTS:
https://www.aliyun.com/product/pts[2] QA Intelligence:
https://qablog.practitest.com/相關内容
如何做好性能壓測(一)丨壓測環境設計和搭建我們是阿裡雲智能全球技術服務-SRE團隊,我們緻力成為一個以技術為基礎、面向服務、保障業務系統高可用的工程師團隊;提供專業、體系化的SRE服務,幫助廣大客戶更好地使用雲、基于雲建構更加穩定可靠的業務系統,提升業務穩定性。我們期望能夠分享更多幫助企業客戶上雲、用好雲,讓客戶雲上業務運作更加穩定可靠的技術,您可用釘釘掃描下方二維碼,加入阿裡雲SRE技術學院釘釘圈子,和更多雲上人交流關于雲平台的那些事。