全鏈路壓測實戰

背景說明

通過全鏈路壓測,模擬真實流量高峯,串聯線上全部系統,讓核心系統同時達到流量峯值:

  • 驗證大促峯值流量下系統穩定性
  • 容量規劃
  • 進行強弱依賴的劃分
  • 降級、報警、容災、限流等演練

通過全鏈路壓測這一手段,對線上系統進行最真實的促銷、搶購、暴擊演練,獲取系統在大壓力時的表現情況,進而準確評估線上整個系統集羣的性能和容量水平,保障系統的穩定性。

性能測試主要有線下單系統單接口、線上單系統以及線上全鏈路壓測等手段。通過不同維度和顆粒度對接口、系統、集羣層面進行性能測試,最終保障系統的穩定性。本篇主要是全鏈路壓測的相關設計和具體的實施。

全鏈路壓測的相關設計

全鏈路壓測,主要就是壓測流量的製造、壓測數據的構造、壓測流量的識別以及壓測數據流向的處理。

整體方案設計如下:
在這裏插入圖片描述

大流量下發器: 其實就是模擬海量的用戶去使用我們的系統,提供壓測的流量,產生大併發的場景和流量;
數據工廠: 構造壓測鏈路中用戶請求的數據,以及壓測鋪底的數據、數據清洗、脫敏等工作。

步驟:
1、壓測平臺負責管理壓測腳本和壓測請求數據,從數據工廠獲取壓測數據集,分發到每一個壓測 agent 機器上。
2、agent 根據壓測腳本和壓力目標對測試機器(測試環境、預發佈、生產環境)發起請求流量,模擬用戶的全鏈路操作行爲(如:查看商品-添加購物車-下單-支付-查看訂單詳情)。
3、被測服務集羣識別出壓測的流量,對於存儲的讀寫走影子存儲。
PS.線上壓測很重要的一點就是不能污染線上的數據,因此需要能夠隔離出壓測的流量,存儲也需要識別出壓測的數據。

以下,介紹壓測流量和壓測數據存儲的隔離方案。

流量識別

要想壓測的流量和數據不影響線上真實的生產數據,就需要線上的集羣能識別出壓測的流量,只要能識別出壓測請求的流量,那麼流量觸發的讀寫操作就很好統一去做隔離了。

壓測流量的識別如下:

同步請求

在這裏插入圖片描述
全鏈路壓測發起的都是Http的請求,只需要在請求頭上添加統一的壓測請求頭,具體表現形式爲:

Header Name:X-Service-Chain;
Header Value:{"test": true}

Dubbo協議的服務調用,通過隱式參數在服務消費方和提供方進行參數的隱式傳遞,表現形式爲:

Attachments:X-Service-Chain;
Attachments Value:{"test": true}

通過在請求協議中添加壓測請求的標識,在不同服務的相互調用時,一路透傳下去,這樣每一個服務都能識別出壓測的請求流量,這樣做的好處是與業務完全的解耦,只需要應用框架進行感知,對業務方代碼無侵入。

中間件

NSQ:通過NSQMessage中添加jsonExtHeader的KV拓展信息,讓消息可以從Producer透傳到Consumer端,具體表現形式爲:Key:test;Value:true

Wagon:對來自影子庫的binlog通過拓展消息命令(PUBEXT)帶上壓測標記{"test": true}

異步線程

異步調用標識透傳問題,可以自行定製 Runnable 或者定製線程池再或者業務方自行定製實現。

數據隔離

通過流量識別的改造,各個服務都已經能夠識別出壓測的請求流量了,那麼如何做到壓測數據不污染線上數據,對於不同的存儲做到壓測數據和真實的隔離呢,主要有客戶端 Client 和 Proxy 訪問代理的方式實現,以下是數據隔離方案:

Proxy 訪問代理隔離

針對業務方和數據存儲服務間已有 Proxy 代理的情況,可以直接升級改造 Proxy 層,存儲使用方完全無感知,無侵入,下面已 MySQL 爲例,說明 Proxy 訪問代理對於壓測數據隔離的方案;
在這裏插入圖片描述

業務方應用讀寫 DB 時,統一與 RDS-Proxy(介於 MySQL 服務器與 MySQLClient 之間的中間件)交互,調用 RDS-Proxy 時會透傳壓測的標記,RDS 識別出壓測請求後,讀寫 DB 表時,自動替換成對應的影子表,達到壓測數據和真實的生產數據隔離的目的。

ElasticSearch、KV 對於壓測的支持也是通過 Proxy 訪問代理的方式實現的。

客戶端 SDK 隔離

在這裏插入圖片描述
業務應用通過 Client 調用存儲服務時,Client 會識別出壓測的流量,將需要讀寫的 Table 自動替換爲影子表,這樣就可以達到影子流量,讀寫到影子存儲的目的。

Hbase、Redis等採用此方案實現。

數據偏移隔離

推動框架、中間件升級、業務方改造,難免會有遺漏之處,所以需要對於壓測的數據統一做偏移,確保買賣家 ID 與線上已有數據隔離開,這樣即使壓測數據由於某種原因寫入了真實的生產庫,也不會影響到線上買賣家相關的數據,讓用戶無感知;

問題:
特殊的週期掃表應用的改造,週期性掃表應用由於沒有外部觸發,所有無法掃描影子表的數據,如何讓這樣的 job 集羣整體來看既掃描生產庫,也掃描影子庫呢?
解決思路:
部署一些新的 job 實例,它們只掃描影子庫,消息處理邏輯不變;老的 job 實例保持不變(只掃生產庫)。

壓測平臺

壓測平臺目前主要負責壓測腳本管理、壓測數據集管理、壓測 job 管理和調度等。

壓測實施流程

全鏈路壓測的執行流程如下:
在這裏插入圖片描述

壓測計劃制定

1、首先需要確認的就是壓測場景
根據運營報備的商家大促活動的計劃,制定大促的壓測場景(比如秒殺、抽獎等),再結合近七天線上流量的場景情況,綜合確定壓測的場景。
2、確認壓測鏈路,壓測的目錄.
如:購買行爲鏈路:購買行爲主要是店鋪首頁-商品詳情頁-下單-支付-支付成功。
3、確認壓測的流量漏斗模型
線上真實的場景案例是,100 個人進入了商家的店鋪首頁,可能有 50 個人直接退出了,有 50 個人最終點擊進入了商品詳情頁面,最終只有 10 個人下了單,5 個人真正付款了,這就是壓測鏈路的漏斗模型,也就是不同的接口的真實調用比例;實際的模型制定會根據近7天線上真實用戶的行爲數據分型分析建模,以及往期同類型活動線上的流量分佈情況,構建壓測鏈路的漏斗模型。
4、確定壓測的目標
根據運營的預估的PV和轉換率情況,結合去年同期線上流量情況和公司業務的增長速率,取大值作爲壓測的目標。

數據工廠

壓測數據工廠主要負責,壓測鋪底數據的準備、壓測請求數據塊的生成。

鋪底數據準備

由於方案採用的是影子庫的設計,因此對於鋪底數據準備需要處理影子庫的數據。
鋪底數據準備的流程圖:
在這裏插入圖片描述
步驟:

  • 數據導入 從生產數據庫按需過濾,導入壓測鋪底需要的數據到大數據集羣的hive表中。
  • 數據處理 在hive表中,對導入的數據進行脫敏和清洗,清洗的目的是保證壓測的數據可用性,比如保證鋪底商品庫存最大、營銷活動時間無限、店鋪正常營業等。
  • 數據導出 對hive標中已經處理完成的數據,導出到已經創建好的影子庫中,需要注意的是同一實例寫入數據的控制(因爲影子庫和生產庫同實例),寫入數據的binlog過濾。

PS.
1、壓測數據的準備,有大數據平臺的基於大數據平臺準備數據。
2、有條件的話,可以實現數據準備的自動化,可維護數據準備job。

壓測請求數據數據集

  • 從各個業務線的表中獲取壓測場景整個鏈路所以接口請求需要的參數字段,存到一張創建好的壓測數據源寬表中。
  • 編寫MapReduce任務代碼,讀取壓測數據源寬表數據,按壓測的接口請求參數情況,生成目標json格式的壓測請求數據塊文件到HDFS。
  • 壓測時,壓測引擎自動從HDFS上拉取壓測的請求數據塊。

壓測腳本準備

梳理壓測請求和參數

採用統一的 RESTful 風格規範,讓各個業務方的人員提交壓測接口的 API 文檔,這樣壓測腳本編寫人員就能根據這份 API 快速寫出壓測的腳本,以及接口的預期結果等。

控制漏斗轉化率

不同場景的配比

對不同的壓測場景鏈路按模塊編寫壓測腳本,這樣的好處就是需要不同場景混合壓測時,只需要在 setUp 時,按需把不同的場景組合到一起即可;需要單獨壓測某一個場景時,setUp 中只留一個場景就好,做到一次編寫,處處可壓。

壓測執行

1、可以通過壓測平臺執行
2、可以藉助工具執行(如:Jmeter、loadrunner、ab等)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章