系統性能測試的幾個痛點
在金融、零售快消、物流、新能源等傳統行業,通常都會有一個相對獨立的測試團隊,其中包括了性能測試。

過去性能測試通常是開發自測、或以項目需求驅動的方式實施,也就是根據需求在測試環境驗證相應的性能目標,出具性能驗收報告后就算結束。但隨着業務系統的迭代速度不斷加快,這種做法也會存在諸多不足:
首先,測試環境得出的測試結果,可以驗證程序級問題,但因環境和數據的差異,無法驗證或獲得業務系統在生產環境的性能指標。
其次,隨着業務需求變更的頻率不斷加快,發布周期隨之縮短,很多緊急項目直接跳過性能測試就上生產。也造就了一個行業誤區:功能一定要測,性能可以不測。舉個例子,比如說變更數據庫連接數則是一個反例。
第三,據了解過的大多企業,為了生產系統的安全,日常水位很低,比如CPU利用率不到10%,高峰時期可能達到20%。之所以資源利用率低,也是因為對生產容量的不確定性所造成。
另外,以項目需求驅動測試的做法,測試結果將會是數據孤島,很難做到可持續的性能基線跟蹤和風險識別,容易引發累積雪崩性問題。
性能測試成熟階段
目前業內並沒有針對性能評測的成熟度的評估模型,根據過往的行業實踐經驗,大致可將其定位為五個階段。

第一階段,以開發自測為主,初創型企業在該階段居多,沒有獨立的性能測試團隊,系統開發完成后,開發人員自行用開源工具針對核心接口進行壓測,缺乏專業的測試方法。
第二階段,以項目需求驅動為主,測試團隊被動領活干,測試團隊基於項目需求設計測試場景對被測系統進行相應評測,測試需求與測試目標大多依賴人工評審。
第三階段,以瀑布模式為主,擁有獨立的性能測試團隊,並制定統一的的性能准入/准出標准和規范,通過組織形式推廣整個IT部門,實施規范化的性能測試驗收過程。
第四階段,化被動為主動,用平台化方式對關鍵業務變更形成一套完整的性能回歸體系,打通持續集成,依托迭代性能評測數據建立可持續的性能基線跟蹤機制,識別頻繁迭代變更帶來的性能隱患。
第五階段,測試左右賦能,向左賦能於研發,提前識別潛在性能風險,向右賦能於運維,為生產容量、穩定性提供有效保障手段。
壓測方法逐步演進
從最初的線下單系統、單模塊以及短鏈路壓測,轉變為生產全鏈路壓測。

線下壓測階段
最早在螞蟻金服,壓力測試是在測試環境進行,且是針對一些重點項目,比如余額寶、花唄、借唄等明星型項目,由於項目的重要性,將會由專職的性能測試專家介入參與評估。后由於公司的核心業務日益增多,逐步開始在測試環境進行迭代變更回歸測試,並形成多版本性能對比評估機制。這種測試手段,難以用測試環境得出的結果推導生產真實容量。
引流壓測階段
隨着業務量的不斷增長,考慮到線下測試結果的准確性,開始嘗試生產壓測,這種壓測手段,我們稱之為引流壓測。事實上沒有真正的模擬放大壓力進行測試,而是一種通過縮小在線服務集群數的方式來放大單機處理量。比如一個業務系統的集群有100個節點,將其中90個節點模擬下線或轉發流量到剩余的10個節點上實施壓測,如圖所示。

引流壓測的弊端在於,DB承受壓力不變,上下游系統的壓力不變。壓測結果僅能代表單個應用的性能,但往往無法識別鏈路和架構級的隱患,而且在引流過程中倘若出現異常或突如其來的業務高峰,很容易造成生產故障。
全鏈路壓測
隨着壓測技術和手段的不斷演進,在2014年初,全鏈路壓測的方法開始誕生,其目標是希望在大型促銷活動來臨前,可以在生產環境上模擬路演進行驗證整體容量和穩定性。由此,出現了全鏈路壓測方法所涉及的公網多地域流量模擬、全鏈路流量染色、全鏈路數據隔離、全鏈路日志隔離、全鏈路風險熔斷等關鍵技術。

多地域流量模擬技術是指,通過全國各地CDN節點模擬向生產系統施加壓力,並在壓測過程中對生產系統健康度進行實時監控,快速識別壓測對生產業務帶來的風險,立即作出流量調節或熔斷決策。
全鏈路壓測改造的四大核心能力

- 全鏈路流量染色,通過壓測平台對輸出的壓力請求打上標識(如圖),在訂單系統中提取壓測標識,確保完整的程序上下文都持有該標識。
- 全鏈路日志隔離,當訂單系統向磁盤或外設輸出日志時,若流量是被標記的壓測流量,則將日志隔離輸出,避免影響生產日志。
- 全鏈路風險熔斷,當訂單系統訪問會員系統時,通過RPC協議延續壓測標識到會員系統,兩個系統之間服務通訊將會有白黑名單開關來控制流量流入許可。該方案設計可以一定程度上避免下游系統出現瓶頸或不支持壓測所帶來的風險。
- 全鏈路數據隔離,當會員系統訪問數據庫時,在持久化層同樣會根據壓測標識進行路由訪問壓測數據表。數據隔離的手段有多種,比如影子庫、影子表,或者影子數據,三種方案的仿真度會有一定的差異。
如何做到全鏈路監控分析
全鏈路的監控和分析包括三個層面。第一層是用戶體驗監測,在雲壓測平台中可以看到用戶的感受,比如響應時間是否隨着壓力的加大而變長。假如耗時突增引發業務下跌,我們將進入第二層監控,快速從用戶體驗側下鑽到生產系統后端鏈路,並快速識別出現問題的服務節點或接口。
依托於以上監控信息,需要利用相關分析能力快速給出應急決策依據,比如通過重啟解決會有何影響?同時,在故障發生過程中,分析系統將會保留現場,也會繼續下鑽到第三層分析,比如深度追蹤某個接口或方法中的所有執行邏輯耗時,再比如為什么CPU會突然暴增、GC暫停時間長等。
三層分析能力的結合和聯動,比傳統APM相關技術監控粒度更深,同時具備分析和優化建議能力。同時,在生產環境的變更灰度、故障演練也都可以依托於壓測流量進行,這樣降低在生產流量下直接演練的風險。

線下環境壓測很有必要
這一點,值得特別提出,2015年我們曾犯過一個錯誤:有了生產壓測,線下壓測基本不做了,就因為這種心態,導致:
-
很多程序變更所引起的一些基本的程序級問題沒有得到驗證。
-
導致生產壓測過程中頻繁出現故障。
因此,我們又重新把線下回歸體系撿了起來,甚至花了較大精力去完善這個線下回歸體系。
總而言之,線下壓測是無風險發現程序級問題,線上壓測是低風險實現線下補足和評估生產的容量。

全鏈路壓測體系落地實例
我們有個合作企業“性能評測體系建設”的案例:這個企業一開始屬於前面講過的成熟度階段的5級中的第2-3級,每年大概有200個左右的項目,團隊大,有幾十個性能測試人員,回歸業務量非常大,迭代周期是雙周,當時用戶最大的挑戰是測試需求量大導致人力投入大,並且無法在發布前完成評測工作。在合作后,一方面依托平台化能力,另一方面優化組織協同模式、規范化、體系化,在為期不到半年時間組織能效提升4-6倍,同時一定程度上提升了壓測環境資源的利用率,降低資源投入成本。

另外,還有一個生產全鏈路壓測的案例:在為一個企業實施生產壓測時,偶發性出現用戶相應很慢,通過全鏈路下鑽深度分析,發現這些特定的用戶訪問時,Redis調用非常頻繁,當特定用戶集中訪問時,整個Redis達到容量瓶頸,最終影響到所有用戶。

最后,我們再舉一個因開源組件BUG導致的CPU使用暴增引發的故障。在一次壓測過程中,我們發現一個服務節點上的某個CPU消耗100%,我們利用平台的深度熱點方法分析能力,發現CPU利用率排在第一的方法是通訊框架Netty的內存清理邏輯。經排查,發現是Netty的BUG(高並發下出現死循環),我們本想修復,后發現在其官方4.1.25版本已修復,升級后CPU占滿的情況完全消退。最終不僅解決了CPU利用率高的問題,業務的TPS也從2491提升到3040。

總結
第一,不能有了生產全鏈路壓測就不做線下壓測;
第二,不是有了生產影子表能力,就可以在生產隨意實施壓測。比如日志也需要隔離,如果生產日志和測試日志混為一體,將會影響大數據分析(如用戶行為分析)。同時生產壓測本身是高風險的行為,所以壓測前中后的生產穩定性風險防控能力也至關重要。
