轉自:https://www.cnblogs.com/zingphoy/p/12824461.html
可以很好的套用到自己的項目中
正文:
博文的內容並不都是我原創的,行文思路來源於一次內部分享,再結合網上衆多參考資料總結出來的,算是一個學習筆記。
可能很多QA、RD同學跟我都一樣,對服務端壓測一直沒有系統的認知,印象停留在使用壓測工具如Jmeter對單接口發壓,調整線程數和循環數來製造不同壓力,最後計算一下TPS和成功率等就完事了?網上雖然有不少壓測相關的文章,但多數是壓測工具的入門級使用,有的是壓測流程和指標的簡單解釋,或者就是幾個大廠牛逼的全鏈路壓測能力和壓測平臺的介紹。這些文章要不缺少系統性闡述,要不過於抽象不好理解,對沒怎麼接觸過壓測的同學不太友好。
本文嘗試在QA角度梳理一次完整的壓測過程,嘗試總結更爲普適的壓測思路,給大家提供更有意義的參考。
測試分很多種,網上很多文章[1]會玩弄概念,搬出來3個名詞:壓力測試(Stress Testing)、性能測試(Performance Testing)、負載測試(Load Testing)。一般情況下並不需要做這麼細粒度的概念區分,這3個概念我覺得是沒辦法完整區分各自邊界的,至少在程序邏輯上難以做得到,更多差異只是來自於不同的壓測策略,所以儘管忽略這幾個概念的區別,都叫它壓測或者性能測試即可。
拿技術人熟知的阿里舉例,應該是國內做壓測最好的一個大廠。外界熟知的阿里2012雙11活動,2012年11月11日零點,阿里各種系統報錯、立刻下單報錯、購物車支付報錯、支付系統報錯、購物車的東西丟失,系統顯示交易成功率不到50%,產生了大量超賣,給阿里帶來很大的損失。那一年的雙11後,庫存、商品、退款和相應數據庫的同學,爲了處理超賣導致的問題,沒日沒夜加了兩週的班,同時給了用戶不少糟糕購物體驗。
爲什麼出現這麼嚴重的問題?因爲對整個全交易鏈路上的各個子系統的承受能力不清楚,並且錯誤預估了可能會達到的流量,也沒有完善的預案,兵敗如山倒。
2013年阿里首次提出了全鏈路壓測方案:一方面可讓鏈路的各個系統知道自己的承壓極限;另一方面可讓各個系統有個明確的優化目標,瞭解到整個鏈路的瓶頸並評估資源情況。
爲什麼只做單系統壓測還不夠呢?
在活動開始的瞬間,各系統都面臨自身服務的巨大的壓力,而系統之間是有互相依賴關係的,單機壓測沒有考慮到依賴環節壓力都比較大的情況。一個系統出現故障,故障會在鏈路流轉過程中層層累加,會造成無法評估的影響。
所以最可靠的方式是完全模擬真實場景來壓測,通過線上全鏈路壓測提前發現問題。
完整的壓測流程一般包含下面幾個步驟,引用自文末參考資料:
列舉一些常用指標,並不一定都需要關注,根據業務考慮指標的細化粒度。
這裏要說明一下QPS和TPS的區別:
性能測試中,平均值的作用是十分有限的,平均值代表前後各有50%的量,對於一個敏感的性能指標,我們取平均值到底意味着什麼?是讓50%的用戶對響應時間happy,但是50%的用戶感知到響應延遲?還是說50%的時間系統能保證穩定,而50%的時間系統則是一個不可控狀態?
平均響應時間這種指標,只有在你每次請求的響應時間都是幾乎一樣的前提下才會有一樣。再來個例子,人均財富這個概念有多沙雕相信大家也明白,19年有個很搞笑的新聞——騰訊員工平均月薪七萬,明白平均值多不靠譜了吧😂。下圖是現實世界中一個系統的響應時間柱狀圖,RT在前20%的請求數較少,但是因爲耗時特別短(拉高了均值可能是命中緩存,也可能是請求的快速失敗),而大多數RT是在均值之下,那纔是系統的實際性能情況。
所以說,我們不應看最好的結果,相反地,應該控制最壞的結果,用戶用得爽他不保證會傳播好口碑,但是用戶用到生氣他保證變爲鍵盤俠肆意大罵,這也是爲什麼平均值無法帶來足夠的參考,因爲happy的結果矇蔽了我們的雙眼,平均值在壓測中丟失太多信息量。
總結一下,較爲科學的評估方法應該將指標-成功率-流量
三者掛鉤在一起的:
xx%的響應在xx毫秒內返回,其中成功率爲xx%。
根據這個方針,可以得到一些測試思路:
壓測開展前是需要有目標的,也就是有期望的性能情況,希望接口或系統能達到的性能預期,沒有目的的壓測是浪費人力,下面給出幾種目標預估的方法。
歷史監控數據
已經上線並且有歷史監控數據的接口,可以查看歷史數據,找出峯值QPS和PCT99。🌰 若接口A已經上線並且做了監控,在經過某次大活動或者上線時間足夠長後,存量監控數據就可以使用了。
類比
新接口或者線上未監控的接口,不存在歷史數據,但存在類似功能接口的歷史監控數據,可以通過類比得出壓測的目標。🌰 假設上一年淘寶雙十一下訂單接口QPS=x,RT=y,這一年天貓平臺整起來了,雙十一活動與上年淘寶雙十一活動場景類似,也沿用QPS=x,RT=y的目標(例子不嚴謹,理解即可)。
估算
新接口或者線上未監控的接口,不存在歷史數據,且不存在類似功能接口的數據可供參數考,此時需要估算峯值,常用方法有8/2原則
——一天內80%的請求會在20%的時間內到達。
top QPS = (總PV * 0.8) / (60 * 60 * 24 * 0.2)
RT如無特殊要求,一般採用默認值:
🌰-1 電商秒殺活動,預估同時有1000w人蔘與,簡單起見假設總QPS是1000w。由於前端不同的秒殺倒計時形式使得請求有2s的打散,再加上nginx等webserver做了20%機率拒絕請求的策略,所以下單接口總QPS = 1000w / 2 * (1 - 0.2) = 400w/s,最終壓測目標爲400w/s的QPS。
🌰-2 電商全天低價搶購活動,屠龍寶刀,點擊就送,一刀99級,emmmmm跑題了。根據8/2原則,預估在午休(12-1)和晚上下班後(7-10)共4h是流量高峯,估算接口峯值QPS = 活動全天接口PV / (4*3600s)。
其他
除了前面說到的情況,肯定還有一些我們無法下手的三無接口,無參考、無預估、無歷史數據,這時候只能一點一點來,慢慢把壓力提上去的同時收集數據,最終得出接口的最優處理能力。
壓測是有目的的壓測,也就是說不是隨便找些接口發一通壓力,而壓測全部的接口也是做不到的或者說無意義的,得有壓測的優先級,所以梳理壓測場景是很重要的。高優場景主要有下面幾個:
壓測有分單接口壓測和場景化壓測,前者會簡單一些,後者一般是多個接口混合操作以組成一個業務場景,兩者在方法上是相通的。
梳理場景時QA需要與RD對齊,確認不同接口的RD負責人、需要壓測的接口、系統性能現狀以及壓測目標;在確定每個接口的壓測目標時,要考慮到壓測對象是單實例單機房還是集羣;在細節上也要確認是單接口壓測還是場景化壓測,每個接口的流量佔比以及優先級,需不需要發足夠的壓力來觸發系統的自動擴容或降級等更進一步的運維能力。
在梳理完壓測場景後,就要確認壓測鏈路是否完整或符合預期。從一個服務到另一個服務,是不是鏈路上每一個服務都要壓到?下游服務如審計安全等是不是已經考慮到?壓測過程中產生的髒數據是否會影響線上數據?可能還要細化到具體下游某個服務不參與壓測,如何處理呢?以上種種問題,可能需要推動整個鏈路相關的業務方進行對應業務改造來適配壓測流量,改造完後還要自測驗證才能正式開始壓測,下面講一些重點問題,部分內容引用自[文末的參考資料][全鏈路壓測的大概思路]。
髒數據問題
is_stress
標記,存儲層根據標記區分壓測流量,對壓測數據添加指定前後綴再入庫等特殊處理不參與壓測的服務如何處理
可以獨立部署一套線下環境進行壓測。在不影響線上環境的前提下,確保機房,網絡,存儲,上下游服務與線上保持一致,部署一套獨立的環境進行測試,機器與線上隔離,機器出問題不會影響線上。這種方式壓測只是針對較少的幾個系統進行,因爲很難把整個鏈路所有系統都獨立再部署一套,所以應用範圍有限。
備註:上游、下游如何定義? RFC 2616
Upstream and downstream describe the flow of a message: all messages flow from upstream to downstream.
下游的輸入來自於上游的輸出,假設有服務A、B,A調用了B(或者說A依賴B),那B就是A的上游,A就是B的下游,因爲A的輸入來自於B的輸出(A調用了B,獲取B的輸出)。
更簡單地理解,越接近用戶的東西,越是下游。
更常見的方法是直接使用線上環境壓測,在機器負載低的時間段(如深夜)人工發起或定時發起壓測。
確認好壓測流程的技術支持和Mock數據的支持後,還要確認壓測鏈路的監控體系是否完整,一來方便在壓測過程中及時發現問題,二來是爲了積攢歷史壓測數據,三來順便確認監控系統本身是否可靠且全部到位。一般監控項包括(也就是壓測指標):
壓測數據其實沒什麼神祕的,網上說什麼按照業務模型產出數據,表達上做了過度抽象反而不好理解,其實意思就是按照業務核心場景將所需要的數據構造出來。關鍵是要如何科學地模擬線上數據分佈,引用文末參考資料,阿里雙十一大促中有如下的業務流量漏斗模型,需要給不同場景科學地分配流量比例,這個比例是分析出來的而不是拍腦袋的。可以想象,阿里大促的流量不可能全部最後都走到付款流程,必然很多流量會在前面的流程就結束了,也就意味着,你把全部壓測數據都構造成【走到付款場景】的話,你的壓測結果是不準確的。
爲了更好模擬線上真實的用戶使用場景和數據,dump線上數據用來壓測是很常見的手段,有兩種簡單思路:
數據dump下來是不能直接用的,一來沒加壓測標記會污染線上數據,二來涉及用戶隱私數據。可以將線上數據作爲數據源,經過採集、過濾、脫敏等操作後轉變爲壓測數據,注意點有:
基本思路跟做質量保障是一樣的,從細粒度開始慢慢集成到整個大系統,就像單測->接口測試->集成測試
,壓測也是先從簡單的開始,一步一步走向全資源全鏈路,可以參考過程:單接口單機->單接口1/4資源->場景化1/4資源->全量資源壓測->撥測
。
在單核(或物理資源少)機器上部署單個服務,排除外部鏈路、網絡等因素,得出自身服務的單核性能情況(單位QPS/core),後續根據此單核性能指標結合壓測目標值進行擴容。另外由於是壓的單接口單機,無其他接口請求影響,上下游在足夠資源的情況下也不會造成瓶頸,所以能確保服務的性能真實值。
單接口單機可以在正式開始大規模壓測前提前發現問題,方便RD做針對的性能優化並快速檢驗優化效果。一部分問題會先在單接口單機壓測環節中發現,而一些隱藏得更深的問題,需要延後到全鏈路大流量壓測才能暴露。
單接口單機壓測環節,服務端已經完成了部分性能優化,接下來可以進入單接口1/4資源壓測,這樣是爲了驗證在單接口單機壓測中得到的單核性能數據,在擴容1/4資源下性能是否會線性增長,是否存在性能損耗以及定位損耗源。
單接口壓測侷限很明顯,場景化壓測由於引入了上下游服務的其他接口的因素,可以發現單接口壓測無法發現的問題,更接近線上用戶場景。
全部資源到位後,預估的線上壓力是否能承受,這一步也是內網壓測過程的最後一步。
除了做內網壓測,還要進行撥測驗證用戶從客戶端到服務端的整個帶寬資源是否滿足預期,內網壓測已經確認了業務性能是否達標,因此撥測可以只選擇了一個場景進行驗證即可。(簡單來說撥測相當於壓測cdn,檢查各地cdn節點資源是否充足)
壓測過程也要提前規劃好,然後加入一定的人工策略調整。阿里大促還會有預熱環節,預先跑一部分流量使得該緩存的數據提前緩存起來。正式壓測時細分有幾種壓測策略,引用自文末參考資料:
除了關注前面講到的指標外,還需要關注各機房流量是否均勻(若不均勻要確認負載均衡是否work)。
發壓環節的結束並不代表壓測就到此爲止。
如果使用了影子表,可能收尾工作會簡單一些,只需要下掉影子表即可。如果數據直接落到了線上數據庫,可能一大堆壓測數據要清理,壓測時會對數據染色(比如指定測試賬號或流量攜帶壓測標記),逐層透傳,最後根據標誌識別刪除。
舉例一些可能會發現的典型問題:
……
給出一個完整的壓測過程例子:
壓測最終應該輸出一份報告總結,其實也就是把整個壓測方案、過程、結論記錄下來,寫明壓測目標、壓測接口、壓測數據、壓測結論,給出發現的問題並提供優化方案。往往在壓測報告完成時,性能問題已經基本被解決了,報告的意義在於梳理前面的整個流程,給後續的壓測提供經驗指導。
Why Averages Suck and Percentiles are Great