併發模式與 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,以及 接口一、接口二、接口3 的響應時間分別爲RT一、RT二、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 ,經過併發模式拿到指導運維進行容量規劃的結果,是要付出的代價會很是大的,甚至也不能達到想要的結果。

在真實狀況下,接口一、接口二、接口3的 RPS 是不同的,拋開接口異常斷言失敗不繼續調用後面的接口的狀況,接口 RPS 關係是呈倒金字塔分佈,比方說,瀏覽商品(接口)了以後不必定會去下單購買(接口),由於你們通常會反覆瀏覽不一樣的商品選擇最中意的再下單,因此瀏覽商品(接口)的 RPS 必然會比下單購買(接口)的 RPS 要高,用戶有放棄繼續「走下一步」的權利,可是這種狀況你若是嘗試對併發的分佈來建模,是一個很是龐大且複雜工程問題,由於影響的因素實在太多了。

以下圖所示,併發壓測模式下,全部接口的 RPS 都是同樣的,與「實際狀況」(圖右部分)截然不同。

受傳統性能測試思路的影響,目前有接近90%的企業用戶(數據來源於 阿里雲PTS ) 將併發模式性能測試的結果做爲穩定性、容量驗收的依據,因此說這是一件很是恐怖的事情。

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

在這裏我很是樂意跟你們分享一份來源於 QA Intelligence《State of Testing™ Report 2019》關於2016~2019年軟件開發模式的調查數據:

軟件開發模式佔比(201九、201八、201七、2016)

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

想到了一句很是「膚淺」但有點道理的話,「性能問題優化以後最終均可以轉化爲容量問題」,簡單地能夠理解爲測試同窗發現了性能瓶頸,而後開發同窗通過了優化,運維同窗根據優化以後的系統的能力進行擴容或者縮容。瞧!這不就是開發、測試和運維完美協做的一個典型實踐嘛?!

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

容量規劃的核心有一張已經用的「泛黃」的圖,你們應該一看就明白,有兩個核心指標:

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

上面提到一個概念叫作「流量模型」,這個流量模型你能夠近似的認爲就是前面圖中「實際狀況」的 RPS 倒金字塔,他有兩個要素:

  • 接口範圍
  • 每一個接口的RPS

容量規劃的目的性很是強,也就是在特定「流量模型」下,給出資源分配的最優解。在壓測實施的時候,壓測的主體是接口的 RPS,按照流量模型進行試壓。(若是你還在想爲何主體是 RPS 而不是併發的話,請在仔細閱讀前面那章)

RPS 模式壓測在容量規劃的典型應用,是併發模式沒法實現的。正式由於此,咱們才能將性能測試從「定性分析」轉化爲「定量分析」。

阿里在2013年構建了一整套基於線上全鏈路壓測的容量規劃體系,逐漸替代以前單應用、單接口這種低效的容量評估手段,過程也是很是曲折的。容量規劃是一個很是大的課題,本文的重點不是「容量規劃」,若是你對「智能化全鏈路容量規劃」感興趣,請在文末留言或加入咱們的性能壓測交流釘羣。

結尾:無心引戰

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

固然,我無心引戰,併發模式、RPS 模式、你想要的和你尚未想到將來想要的均可以在 阿里雲PTS 上找到。

本文做者:韓寅,花名隱寒,阿里雲PTS 高級技術專家,2014年加入阿里巴巴,一直從事性能測試和高可用領域的相關工做。



本文做者:中間件小哥

原文連接

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索