1 阿里分享
2013年為了雙11提前預演而誕生,該服務已提供在阿里雲PTS鉑金版。
1.1 可用性及單機壓測問題
1.1.1 系統可用性問題
經常由下面一些不確定性因素引起:
- 系統容量
- 業務性能
- 基礎設施瓶頸
- 中間件瓶頸
- 系統直接的依賴影響
1.1.2 傳統線上單機與單系統壓測的四種方式
- 模擬調用者壓測生產環境:讀請求+寫請求(需要特定處理)
- 流量錄制和回放:快速率回放對單機壓測
從流量分配的角度,將流量集中到某台機器(這兩種方式要求訪問流量不能太小):
- 請求流量轉發
- 改變負載均衡的權重
1.1.3 單系統壓測的問題
- 在做單個系統的容量規划時,所有的依賴環節能力是無限的,進而使得我們獲取的單機能力值是偏樂觀的;
- 采用單系統規划時,無法保證所有系統均一步到位,大多數精力都集中核心少數核心系統;
- 部分問題只有在真正大流量下才會暴露,比如網絡帶寬等等。
1.2 全鏈路壓測組成
單鏈路指一個業務線。
全鏈路壓測是一個模擬線上環境的完整閉環,由5大核心要素組成:
- 壓測環境:對應用戶真實的線上環境,具備數據與流量隔離能力的生產環境; 原則:能夠用中間件解決的問題,絕不對業務系統進行改造,系統所需做的是升級中間件,這一原則極大提高了工作效率。
- 壓測基礎數據:構造滿足高峰場景的核心基礎相關數據,影子庫里構造相同量級的數據; 真實線上數據篩選脫敏。
- 壓測流量(模型、數據):成百上千的接口組合,到復雜的接口之間的參數傳遞,復雜的條件判斷來構造精准的全局流量模型,和真實業務情況保持一致;
> 壓測引擎的三層結構:- 協議支持
- 請求發送:CGroup資源隔離,異步Reactor模型發送請求,鏈路間線程池隔離
- 集群協作: Master,Slave長連接; Cristian算法同步網絡延遲,Slave動作一致;
- 流量發起:模擬全國各地真實的用戶請求訪問,探測站點能力;
- 問題定位:多維度的監控和報表,服務端可通過其他生態產品協助定位。
翻譯構造能力的體現:便捷的構造全局業務場景和流量數據的能力。
原子因素:鏈路(被壓測的最小單位) 指令: 思考時間、集合點、條件跳轉、cookie存取、全局准備、並發用戶限制等
原子因素->串行鏈路->場景
1.3 超限后的流量控制
- 丟棄請求
- 對下游降級
- 黑白名單
- 請求排隊
1.4 流量平台數據量
- T級別的壓測請求數據
- 每秒1600W+次請求壓測能力
- 維持1億+的無線長連接和登陸用戶
- 秒級的智能數據調度和引擎調度能力
2 京東分享
ForgeBot, 2016年開發
最早基於開源的NGrinder,能勝任單業務壓測。Controller功能耦合重,支持的Agent數量有限。 之后開發了ForgeBot。
2.1 主要功能模塊
- Controller:任務分配
- Task Service:負載任務下發,支持橫向擴展。提供任務交互和注冊服務。(gRPC:HTTP2+protobuf3)
- Agent:注冊心跳,拉取任務、更新任務狀態、 執行和停止worker process(采用Docker容器部署)
- Monitor Service:接受並轉發壓測數據給JMQ
- DataFlow:對壓測數據做流式計算(輸出TPS,TP999,TP99,TP90,TP50,MAX,MIN),將計算結果存到DB(ES)
在管理端創建測試場景,Controller掃描發現場景,尋找空閑Agent資源。
任務分配時,Controller計算每個間隔的執行時間點和遞增的虛擬用戶數,由Agent動態加壓減壓。
在多個組件使用了gRPC框架通訊
分讀壓測和寫壓測
2.2 一些解決問題的思路
問題:如何模擬在某一個瞬間壓力達到峰值?
解決方案:通過集合點功能實現,提前開啟峰值所需足夠數量的線程,通過計算確定各個時間點上不需要執行任務的線程數量,通過條件鎖讓這些線程阻塞。當壓力需要急劇變化時,我們從這些阻塞的線程中喚醒足夠數量的線程,使更多的線程在短時間進入對目標服務壓測的任務。
問題:為了計算整體的 TPS,需要每個Agent把每次調用的性能數據上報,會產生大量的數據,如果進行有效的傳輸?
解決方案:對每秒的性能數據進行了必要的合並,組提交到監控服務
3 餓了么分享
3.1 業務模型的梳理
- 是否關鍵路徑
- 業務的調用關系
- 業務的提供的接口列表
- 接口類型(http、thrift、soa等)
- 讀接口還是寫接口?
- 各接口之間的比例關系
3.2 數據模型的構建
3.2.1 寫請求
壓測方法:
- 用戶、商戶、菜品等在數量上與線上等比例縮放;
- 對壓測流量進行特殊標記;
- 根據壓測標記對支付,短信等環節進行mock;
-
根據壓測標記進行數據清理;
讀請求
壓測方法:拉取線上日志,根據真實接口比例關系進行回放
3.2.2 無日志服務
壓測方法:
- 構建壓測數據使緩存命中率為0%時,服務接口性能,數據庫性能;
- 緩存命中率為100%時,服務接口性能;
- 緩存命中率達到業務預估值時,服務接口性能;
3.3 壓測工具
定制JMeter
3.4 壓測指標監控和收集
- 應用層面
- 服務器資源
- 基礎服務:中間件和數據庫
要點:
- 響應時間不要用平均響應時間,關注95線;
- 吞吐量和響應時間掛鈎
- 吞吐量和成功率掛鈎
3.5 具體實現
SpringBoot+AngularJS.
測試期間產生的冷數據(用例數據、結果數據)持久化至MongoDB,熱數據(實時數據)持久化至InfluxDB並定期清理。
分布式測試:重新實現JMeter的分布式調度
測試狀態流轉:各種流程形成閉環,要考慮各種異常。
主要流程:配置 -> 觸發 -> 運行 -> 結果收集 -> 清理。
整個狀態流轉的實現,采用異步Job機制實現了類似狀態機的概念,狀態屬性持久化到數據庫中,便於恢復。
3.6 安全保障
由於是在線上真實環境,需要避免測試引起的服務不可用和事故。
- 權限管理:用戶權限分級管理,不能隨意觸發他人的測試用例,同時高峰期和禁止發布期,不允許執行任何測試。
- 停止功能:這是面向用戶的手動停止功能,用戶可以隨時點擊運行狀態下的測試用例上的停止按鈕,后台會直接kill掉所有運行該測試用例的測試機上的JMeter進程。
- 熔斷功能:系統會根據實時信息中的錯誤率進行判斷,當一定時間內的實時錯誤率達到或超過某個閾值時,該次測試將被自動熔斷,無需用戶干預。
- 兜底腳本:最極端的情況,當整個系統不可用,而此時需要停止測試時,我們提供了一份外部腳本直接進行停止。
