有贊全鏈路壓測實戰

1、前言

有贊致力於成爲商家服務領域裏最被信任的引領者,由於被信任,全部咱們更須要爲商家保駕護航,保障系統的穩定性。有贊從去年開始經過全鏈路壓測,模擬大促真實流量,串聯線上所有系統,讓核心系統同時達到流量峯值:數據庫

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

經過全鏈路壓測這一手段,對線上系統進行最真實的大促演練,獲取系統在大壓力時的表現狀況,進而準確評估線上整個系統集羣的性能和容量水平,不辜負百萬商家的信任。json

有贊對於性能測試主要有線下單系統單接口、線上單系統以及線上全鏈路壓測等手段,經過不一樣維度和顆粒度對接口、系統、集羣層面進行性能測試,最終保障系統的穩定性。這裏主要講述一下,有贊全鏈路壓測的相關設計和具體的實施。服務器

2、總體設計

說到全鏈路壓測,業內的淘寶、京東都都已有很成熟的技術,主要就是壓測流量的製造、壓測數據的構造、壓測流量的識別以及壓測數據流向的處理;直接看下有贊壓測的總體設計:併發

圖片描述

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

壓測平臺負責管理壓測腳本和壓測請求數據,從數據工廠獲取壓測數據集,分發到每個壓測 agent 機器上,agent 根據壓測腳本和壓力目標對線上機器發起請求流量,模擬用戶的查看商品-添加購物車-下單-支付等行爲,線上服務集羣識別出壓測的流量,對於存儲的讀寫走影子存儲。這裏就要說到,線上壓測很重要的一點就是不能污染線上的數據,不能讓買賣家有感知,好比壓測後,賣家發現多了好多訂單,買家發現錢少了。因此,線上服務須要可以隔離出壓測的流量,存儲也須要識別出壓測的數據,下面看一下有讚的壓測流量和壓測數據存儲的隔離方案。框架

3、流量識別

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

3.1 同步請求

圖片描述

全鏈路壓測發起的都是Http的請求,只須要要請求頭上添加統一的壓測請求頭,具體表現形式爲:
Header Name:X-Service-Chain;
Header Value:{"zan_test": true}oop

Dubbo協議的服務調用,經過隱式參數在服務消費方和提供方進行參數的隱式傳遞,表現形式爲:
Attachments:X-Service-Chain;
Attachments Value:{"zan_test": true}性能

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

3.2 中間件

  • NSQ:經過 NSQMessage 中添加 jsonExtHeader 的 KV 拓展信息,讓消息能夠從 Producer 透傳到 Consumer 端,具體表現形式爲:Key:zan_test;Value:true
  • Wagon:對來自影子庫的 binlog 經過拓展消息命令(PUB_EXT)帶上壓測標記{"zan_test": true}

3.3 異步線程

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

4、數據隔離

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

4.1 Proxy 訪問代理隔離

針對業務方和數據存儲服務間已有Proxy代理的狀況,能夠直接升級 Proxy 層,存儲使用方徹底無感知,無侵入,下面以 MySQL 爲例,說明 Proxy 訪問代理對於壓測數據隔離的方案;

圖片描述

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

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

4.2 客戶端SDK隔離

圖片描述

業務應用經過Client調用存儲服務時,Client 會識別出壓測的流量,將須要讀寫的 Table 自動替換爲影子表,這樣就能夠達到影子流量,讀寫到影子存儲的目的;

Hbase、Redis 等採用此方案實現

4.3 數據偏移隔離

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

這裏要說一下特殊的週期掃表應用的改造,週期性掃表應用因爲沒有外部觸發,全部沒法掃描影子表的數據,如何讓這樣的 job 集羣總體來看既掃描生產庫,也掃描影子庫呢?
有讚的解決思路是,部署一些新的 job 實例,它們只掃描影子庫,消息處理邏輯不變;老的 job 實例保持不變(只掃生產庫)

5、壓測平臺

有讚的全鏈路壓測平臺目前主要負責壓測腳本管理、壓測數據集管理、壓測 job 管理和調度等,後續會有重點介紹,這裏不作深刻

壓測的「硬件」設施基本已經齊全,下面介紹一下有贊全鏈路壓測的具體實施流程吧

6、壓測實施流程

廢話很少說,直接上圖:

圖片描述

有贊全鏈路壓測的執行流程如上圖所示,下面具體看一下幾個核心步驟在有贊是怎麼作的。

6.1 壓測計劃制定

要想模擬大促時線上真實的流量狀況,首先須要確認的就是壓測場景、鏈路,壓測的目錄,以及壓測的流量漏斗模型:

圖片描述

  • 壓測的鏈路:根據公司具體業務具體分析,有贊屬於電商類型公司,大促時候的峯值流量基本都是因爲買家的購買行爲致使的,從宏觀上看,這樣的購買行爲主要是店鋪首頁-商品詳情頁-下單-支付-支付成功,咱們把這一條骨幹的鏈路稱爲核心鏈路,其實大促時主要就是保證核心鏈路的穩定性
  • 壓測鏈路的漏斗模型:線上真實的場景案例是,100我的進入了商家的店鋪首頁,可能有50我的直接退出了,有50我的最終點擊進入了商品詳情頁面,最終只有10我的下了單,5我的真正付款了,這就是壓測鏈路的漏斗模型,也就是不一樣的接口的真實調用比例;實際的模型制定會根據近7天線上真實用戶的行爲數據分型分析建模,以及往期同類型活動線上的流量分佈狀況,構建壓測鏈路的漏斗模型

圖片描述

  • 壓測的場景:根據運營報備的商家大促活動的計劃,制定大促的壓測場景(好比秒殺、抽獎等),再結合近七天線上流量的場景狀況,綜合肯定壓測的場景;

圖片描述

  • 壓測目標:根據運營報備的商家大促預估的PV和轉換率狀況,結合去年同期線上流量狀況和公司業務的增加速率,取大值做爲壓測的目標

6.2 數據工廠

前面咱們已經介紹瞭如何肯定壓測的目標、場景、鏈路,那麼壓測的數據怎麼來尼,這就是數據工廠登場的時候了,下面就介紹一下有贊壓測的數據工廠

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

6.3 鋪底數據準備

壓測準備鋪底的數據,這個衆所周知的,可是因爲有贊壓測的方案採用的是影子庫的設計,因此對於鋪底數據準備不得不去處理影子庫的數據。直接看下鋪底數據準備的流程圖:

圖片描述

  • 數據導入

從生產數據庫按需過濾,導入壓測鋪底須要的數據到大數據集羣的hive表中。

  • 數據處理

在 hive 表中,對導入的數據進行脫敏和清洗,清洗的目的是保證壓測的數據可用性,好比保證鋪底商品庫存最大、營銷活動時間無限、店鋪正常營業等。

  • 數據導出

對 hive 標中已經處理完成的數據,導出到已經建立好的影子庫中,須要注意的是同一實例寫入數據的控制(由於影子庫和生產庫同實例),寫入數據的 binlog 過濾。

有讚的壓測數據準備目前所有在 DP 大數據平臺上操做,基本完成了數據準備操做的自動化,維護了近千的數據準備 job

圖片描述

壓測請求數據數據集

gatling 原生支持 json、csv、DB 等方式的數據源載入,咱們採用的壓測數據源是 json 格式的,那麼如此海量的壓測源數據,是經過什麼方式生成和存儲的尼,咱們的實現仍是依託於 DP 大數據平臺,經過 MapReduce 任務的方式,按需生成咱們壓測請求須要的數據集:

圖片描述

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

MapReduce 生成的數據集 json 示例:
圖片描述

6.4 壓測腳本準備

6.4.1 梳理壓測請求和參數

圖片描述

壓測就要知道壓測的具體接口和接口參數,因此咱們採用統一的 RESTful 風格規範,讓各個業務方的人員提交壓測接口的 API 文檔,這樣壓測腳本編寫人員就能根據這份 API 快速寫出壓測的腳本,以及接口的預期結果等

6.4.2 控制漏斗轉化率

有讚的壓測引擎用的是公司二次封裝的 gatling,原生就支持漏斗比例的控制,直接看例子

圖片描述

6.4.3 不一樣場景的配比

setUp(
    scn0.inject(constantUsersPerSec(10) during (1 minute)).throttle(
      reachRps(300) in (30 seconds),
      holdFor(2 minute)).protocols(CustomHttpProtocol.httpProtocol),
    scn1.inject(constantUsersPerSec(10) during (1 minute)).throttle(
      reachRps(500) in (10 seconds),
      holdFor(3 minute)).protocols(CustomHttpProtocol.httpProtocol),
    scn2.inject(constantUsersPerSec(10) during (1 minute)).throttle(
      reachRps(200) in (20 seconds),
      holdFor(1 minute)).protocols(CustomHttpProtocol.httpProtocol)
  )

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

6.5 壓測執行

壓測的鋪底數據、壓測腳本、壓測請求的數據集都已經介紹完了,可謂是萬事俱備只欠東風,那這個東風就是咱們自建的壓測平臺 maxim,這裏不對壓測平臺的設計展開介紹,展現一下 maxim 在壓測執行過程當中所承擔的工做。
圖片描述

maxim平臺主要的功能模塊有:

  • 測試腳本:負責測試腳本的管理
  • 數據集:負責壓測請求數據集的管理,目前主要有兩種數據集上傳模式:直接上傳數據包和 hadoop 集羣數據源路徑上傳。第二種上傳模式,只須要填寫數據源所在的 hadoop 集羣的路徑,maxim 平臺會自動去所在路徑獲取壓測數據集文件
  • 測試 job:負責測試任務的管理,指定壓測 job 的腳本和腳本入口,以及壓測數據集等
  • 壓測注入器:負責展現壓測注入機器的相關信息
  • 壓測報告生成:壓測報告的生成,直接用的 gatling 原生的報告生成功能

maxim 平臺壓測結果報告

圖片描述

下面看一下壓測執行的頁面功能:
圖片描述

  • 壓力注入器數量:指定本次壓測執行,須要多少臺壓測機去執行
  • 重複場景測試:一個虛擬用戶重複幾回壓測場景
  • 併發用戶數:可執行壓測時,按需填寫須要的每秒加載的併發用戶數和持續時間,無需每次變動壓測腳本
  • 目標 RPS:可執行壓測時,按需填寫壓測的目標 RPS,爬坡時間,目標持續時間,達到限流的做用,可同時指定多個目標 RPS,達到分梯度壓測的目的;

7、最後

到這裏有贊全鏈路壓測方案已經介紹完了,由於篇幅的緣由還有不少實施細節部分並無完整表述,同時有讚的全鏈路壓測也才初具雛形,歡迎有興趣的同窗聯繫咱們一塊兒探討,有表述錯誤的地方也歡迎你們聯繫咱們糾正。

相關文章
相關標籤/搜索