1. 程式人生 > >併發模式與 RPS 模式之爭,效能壓測領域的星球大戰

併發模式與 RPS 模式之爭,效能壓測領域的星球大戰

本文是《如何做好效能壓測》系列專題分享的第四期,該專題將從效能壓測的設計、實現、執行、監控、問題定位和分析、應用場景等多個緯度對效能壓測的全過程進行拆解,以幫助大家構建完整的效能壓測的理論體系,並提供有例可依的實戰。

該系列專題分享由阿里巴巴 PTS 團隊出品,歡迎在文末處加入效能壓測交流群,參與該系列的線上分享。

第一期:《壓測環境的設計和搭建》,點選這裡
第二期:《效能壓測工具選型對比》,點選這裡
第三期:《阿里巴巴在開源壓測工具 JMeter 上的實踐和優化》,點選這裡

1996年, LR 4.0 版本釋出,將效能測試專業理論工具化、產品化,這直接影響之後20多年效能測試領域的理論基礎。但是 LR 作為一款商業化產品,因其價格昂貴,推廣和傳播受限。1998年底,JMeter 開源 ,併發布1.0版本,效能測試領域逐漸蓬勃發展起來。

Loadrunner、Jmeter 引領了效能測試領域的一個時代,功能強大,指令碼化,擴充套件性強,將效能測試標準化、專業化,後續幾乎所有效能測試工具或者商業化產品都馬首是瞻。本文就效能測試做了一個純YY的“實踐”(真的只是純理論分析!),有一些不一樣的思路跟大家一起探討下,望輕踩。

前言:併發、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》的文章,這兩者是等價的。

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?(如下圖)

在平衡狀態下,我們從巨集觀的視角來分析下,整條流水線包裝完一個箱子的 總耗時=(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)

綜上所述,我們可以得出兩個結論:

  • 在平衡狀態下,所有節點的 RPS 必然一樣。
  • 在平衡狀態下,任意節點的 RT 都會影響整體 RPS ,進而會影響併發在節點之間的分配關係。

為了描述方便,我們將節點A、節點B和節點C組成的“100人的流水線”叫做“串聯鏈路”。

節點A的RPS = 節點B的RPS = ... = 串聯鏈路RPS

串聯鏈路RPS = 併發數 / (RT1 + RT2 + ... )

節點N的併發數 = RTn 節點N的RPS = RTn 串聯鏈路RPS**

你確定考慮全面了嗎?

控制併發是目前最為普遍被使用到的壓測模式,打個比方,有一個網站大概會在 下週一10:00 預估有 10w人同時訪問,那麼為了保障網站的問題,很自然的想到使用10w個併發來壓測下整個網站的介面,對應到 JMeter 即為設定執行緒組的執行緒數,對應到 LoadRunner 設定 VU(Visual User)數,很容易理解。

另外,我從阿里雲PTS官方拿到近6個月的資料顯示,選擇併發模式與RPS模式分別佔比 89%與11%,併發模式佔據絕對的規模優勢。

但是,如果你已經充分了解了“RT對於固定併發模式的效能測試的影響”,這裡我不禁要問一句(邪惡臉)“Emm... 你有想過類似Jmeter、LR等併發模式壓測工具拿到的結果是真實的嗎?準確嗎?”。

下面我要講一個“恐怖故事”,先來看一張相對抽象的環境結構圖,

在平衡狀態下,已知總併發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 的因素實在是太多太多了,任何客觀因素的影響都直接影響測試結果的準確性。

併發模式 = 效能瓶頸“定性”分析

在這裡,我更願意定義併發模式效能測試為一種效能瓶頸分析的定性工具,在儘量相同的條件下經過反覆測試,通過分析各個介面的RT構成找到“相對的”效能瓶頸。但是大家有沒有想過,將所有介面優化到極限的效能之後,可以拍胸脯說“我們的系統已經可以抗住 XXX 併發使用者量的訪問了”嗎?答案是否定的,原因有三:

  • 不真實,主要體現在 ① 環境不真實;② 壓測(指令碼)模型不真實;
  • 主體錯誤,併發只是一個誘因和觸發器,影響效能的主體是服務端的RPS;
  • 併發測試的效果真實性依賴於RT,而RT的構成異常複雜。

對了,前面的分析漏了一個影響併發效能測試結果的非常重要的因素:思考時間(使用者在操作的時候,步驟之間使用者會停頓一段時間)。思考時間的引入會將併發的建模的複雜度帶到幾乎不能實現的地步,因為它不像其他相對客觀的因素,它是非常主觀的。假如使用者停留的時間很長,可能是因為感興趣多看一會兒,或者頁面上有100個表單需要填寫,或者看不懂文案是啥意思正在 Google,或者...去衝咖啡了。

有人可能會追問“思考時間究竟要設定多少合適呢?”,我可以非常明確的說“不知道!”,如果你有時間,可以通過大資料 BI 分析統計學意義上的每個介面之間使用者停頓的時間,然後將它設定上,假設每個介面的思考時間總和為 S=(S1+S2+S3),那麼我們可以更新下公式:

T = RPS1 = RPS2 = RPS3 = VU / (RT1 + RT2 + RT3 + S)
介面1的併發 X = T * RT1
介面2的併發 Y = T * RT2
介面3的併發 Z = T * RT3

可以看到,增加了思考時間之後,整體的吞吐量、所有介面的併發都下降了,因為有部分使用者在“思考”。增加“思考時間”有助於提高併發模式下效能測試的準確性,除此之外,還有一些提高併發模式的準確性的手段:

  • 壓測工具地域定製、運營商定製
  • 增加條件跳轉,模擬使用者重試行為
  • 增加集合點
  • ...

這些手段你可以非常輕易的在市面上的開源或者雲測平臺上找到(有些功能可能需要支付一些費用),在這裡不再一一贅述,歸根到底,可以總結為“優化介面 RT 使其接近真實值以提高併發模式的準確性”。

但併發模式始終都受制於“不穩定的”、“難模擬的”、“難預測的”介面 RT ,通過併發模式拿到指導運維進行容量規劃的結果,是要付出的代價會非常大的,甚至也不能達到想要的結果。

在真實情況下,介面1、介面2、介面3的 RPS 是不一樣的,拋開介面異常斷言失敗不繼續呼叫後面的介面的情況,介面 RPS 關係是呈倒金字塔分佈,比方說,瀏覽商品(介面)了之後不一定會去下單購買(介面),因為大家一般會反覆瀏覽不同的商品選擇最中意的再下單,所以瀏覽商品(介面)的 RPS 必然會比下單購買(介面)的 RPS 要高,使用者有放棄繼續“走下一步”的權利,但是這種情況你如果嘗試對併發的分佈來建模,是一個非常龐大且複雜工程問題,因為影響的因素實在太多了。

如下圖所示,併發壓測模式下,所有介面的 RPS 都是一樣的,與“實際情況”(圖右部分)大相徑庭。

受傳統效能測試思路的影響,目前有接近90%的企業使用者(資料來源於 阿里雲PTS ) 將併發模式效能測試的結果作為穩定性、容量驗收的依據,所以說這是一件非常恐怖的事情。

容量規劃:從定性分析到定量分析

在這裡我非常樂意跟大家分享一份來源於 QA Intelligence《State of Testing™ Report 2019》關於2016~2019年軟體開發模式的調查資料:

資料顯示,DevOps 第一次超過 Waterfall(瀑布模式)成為第二位被越來越多的企業接受的開發模式,而瀑布模式等傳統開發模式有逐漸退出歷史舞臺的趨勢。敏捷開發和 DevOps 大行其道,開發、測試和運維等部門、角色之間需要有一種高效的溝通和協作手段。

想到了一句非常“膚淺”但有點道理的話,“效能問題優化之後最終都可以轉化為容量問題”,簡單地可以理解為測試同學發現了效能瓶頸,然後開發同學經過了優化,運維同學根據優化之後的系統的能力進行擴容或者縮容。瞧!這不就是開發、測試和運維完美協作的一個典型實踐嘛?!

這個過程,我們叫做“容量規劃”的實施過程,重點不是容量而是規劃,如果成本不是任何問題,我們可以堆砌無限大的資源,使用者體驗會極其好,但是會造成極大的資源浪費。所以這裡說的“容量規劃”是在保證使用者體驗不受影響(穩定性)的前提下,使有限的資源的利用率最大化(成本)的方法論。打個比方,運維準備了100臺機器,有5個應用,那麼“怎麼分配這100臺機器給5個應用可以使系統既可以正常對外服務又可以使系統達到最大的吞吐量能力”就是容量規劃要解決的問題。

容量規劃的核心有一張已經用的“泛黃”的圖,大家應該一看就明白,有兩個核心指標:

  • 預估的業務量級:對於單應用而言就是這個應用的RPS吞吐量峰值,這個資料一般可以來源於流量模型和歷史資料沉澱;
  • 單臺機器的能力值:在某一個流量模型下,單臺機器系統水位達到安全水位時的RPS峰值。

上面提到一個概念叫做“流量模型”,這個流量模型你可以近似的認為就是前面圖中“實際情況”的 RPS 倒金字塔,他有兩個要素:

  • 介面範圍
  • 每個介面的RPS

容量規劃的目的性非常強,也就是在特定“流量模型”下,給出資源分配的最優解。在壓測實施的時候,壓測的主體是介面的 RPS,按照流量模型進行試壓。(如果你還在想為什麼主體是 RPS 而不是併發的話,請在仔細閱讀前面那章)

RPS 模式壓測在容量規劃的典型應用,是併發模式無法實現的。正式因為此,我們才能將效能測試從“定性分析”轉化為“定量分析”。

阿里在2013年構建了一整套基於線上全鏈路壓測的容量規劃體系,逐漸替代之前單應用、單介面這種低效的容量評估手段,過程也是非常曲折的。容量規劃是一個非常大的課題,本文的重點不是“容量規劃”,如果你對“智慧化全鏈路容量規劃”感興趣,請在文末留言或加入我們的效能壓測交流釘群。

結尾:無意引戰

併發模式與 RPS 模式壓測各有各自的使用場景,併發模式更加適用於對於系統定性的分析,比如幫助定位效能瓶頸,單介面的效能基線沉澱(對比歷史性能優化or劣化);而 RPS 模式在對系統做定量的分析有傑出表現,比如容量規劃、全鏈路效能基線沉澱,當然也可以幫助定位效能瓶頸。併發模式的難點在於 RT 的準確性擬真, RPS 模式的難點在於模型的準確性評估和預測,從實現難度上來說,前者相對於後者來說難度更大一些、掌控度更低一些。

當然,我無意引戰,併發模式、RPS 模式、你想要的和你還沒有想到未來想要的都可以在 阿里雲PTS 上找到。


原文連結
本文為雲棲社群原創內容,未經