一、前言
有贊致力于成為商家服務(wù)領(lǐng)域里最被信任的引領(lǐng)者汞舱,因?yàn)楸恍湃危形覀兏枰獮樯碳冶q{護(hù)航宗雇,保障系統(tǒng)的穩(wěn)定性昂芜。有贊從去年開始通過全鏈路壓測(cè),模擬大促真實(shí)流量赔蒲,串聯(lián)線上全部系統(tǒng)泌神,讓核心系統(tǒng)同時(shí)達(dá)到流量峰值:
- 驗(yàn)證大促峰值流量下系統(tǒng)穩(wěn)定性
- 容量規(guī)劃
- 進(jìn)行強(qiáng)弱依賴的劃分
- 降級(jí)、報(bào)警舞虱、容災(zāi)欢际、限流等演練
- ...
通過全鏈路壓測(cè)這一手段,對(duì)線上系統(tǒng)進(jìn)行最真實(shí)的大促演練矾兜,獲取系統(tǒng)在大壓力時(shí)的表現(xiàn)情況损趋,進(jìn)而準(zhǔn)確評(píng)估線上整個(gè)系統(tǒng)集群的性能和容量水平,不辜負(fù)百萬商家的信任焕刮。
有贊對(duì)于性能測(cè)試主要有線下單系統(tǒng)單接口舶沿、線上單系統(tǒng)以及線上全鏈路壓測(cè)等手段,通過不同維度和顆粒度對(duì)接口配并、系統(tǒng)括荡、集群層面進(jìn)行性能測(cè)試,最終保障系統(tǒng)的穩(wěn)定性溉旋。這里主要講述一下畸冲,有贊全鏈路壓測(cè)的相關(guān)設(shè)計(jì)和具體的實(shí)施。
二观腊、整體設(shè)計(jì)
說到全鏈路壓測(cè)邑闲,業(yè)內(nèi)的淘寶、京東都都已有很成熟的技術(shù)梧油,主要就是壓測(cè)流量的制造苫耸、壓測(cè)數(shù)據(jù)的構(gòu)造、壓測(cè)流量的識(shí)別以及壓測(cè)數(shù)據(jù)流向的處理儡陨;直接看下有贊壓測(cè)的整體設(shè)計(jì):
- 大流量下發(fā)器:其實(shí)就是模擬海量的用戶去使用我們的系統(tǒng)褪子,提供壓測(cè)的流量,產(chǎn)生大促時(shí)的場(chǎng)景和流量骗村;
- 數(shù)據(jù)工廠:構(gòu)造壓測(cè)鏈路中用戶請(qǐng)求的數(shù)據(jù)嫌褪,以及壓測(cè)鋪底的數(shù)據(jù)、數(shù)據(jù)清洗胚股、脫敏等工作笼痛;
壓測(cè)平臺(tái)負(fù)責(zé)管理壓測(cè)腳本和壓測(cè)請(qǐng)求數(shù)據(jù),從數(shù)據(jù)工廠獲取壓測(cè)數(shù)據(jù)集,分發(fā)到每一個(gè)壓測(cè) agent 機(jī)器上缨伊,agent 根據(jù)壓測(cè)腳本和壓力目標(biāo)對(duì)線上機(jī)器發(fā)起請(qǐng)求流量摘刑,模擬用戶的查看商品-添加購物車-下單-支付等行為,線上服務(wù)集群識(shí)別出壓測(cè)的流量倘核,對(duì)于存儲(chǔ)的讀寫走影子存儲(chǔ)泣侮。這里就要說到,線上壓測(cè)很重要的一點(diǎn)就是不能污染線上的數(shù)據(jù)紧唱,不能讓買賣家有感知活尊,比如壓測(cè)后,賣家發(fā)現(xiàn)多了好多訂單漏益,買家發(fā)現(xiàn)錢少了蛹锰。所以,線上服務(wù)需要能夠隔離出壓測(cè)的流量绰疤,存儲(chǔ)也需要識(shí)別出壓測(cè)的數(shù)據(jù)铜犬,下面看一下有贊的壓測(cè)流量和壓測(cè)數(shù)據(jù)存儲(chǔ)的隔離方案。
三轻庆、流量識(shí)別
要想壓測(cè)的流量和數(shù)據(jù)不影響線上真實(shí)的生產(chǎn)數(shù)據(jù)癣猾,就需要線上的集群能識(shí)別出壓測(cè)的流量,只要能識(shí)別出壓測(cè)請(qǐng)求的流量余爆,那么流量觸發(fā)的讀寫操作就很好統(tǒng)一去做隔離了纷宇,先看一下有贊壓測(cè)流量的識(shí)別:
3.1 同步請(qǐng)求
全鏈路壓測(cè)發(fā)起的都是Http的請(qǐng)求,只需要要請(qǐng)求頭上添加統(tǒng)一的壓測(cè)請(qǐng)求頭蛾方,具體表現(xiàn)形式為:
Header Name:X-Service-Chain;
Header Value:{"zan_test": true}
Dubbo協(xié)議的服務(wù)調(diào)用像捶,通過隱式參數(shù)在服務(wù)消費(fèi)方和提供方進(jìn)行參數(shù)的隱式傳遞,表現(xiàn)形式為:
Attachments:X-Service-Chain;
Attachments Value:{"zan_test": true}
通過在請(qǐng)求協(xié)議中添加壓測(cè)請(qǐng)求的標(biāo)識(shí)桩砰,在不同服務(wù)的相互調(diào)用時(shí)拓春,一路透?jìng)飨氯ィ@樣每一個(gè)服務(wù)都能識(shí)別出壓測(cè)的請(qǐng)求流量亚隅,這樣做的好處是與業(yè)務(wù)完全的解耦硼莽,只需要應(yīng)用框架進(jìn)行感知,對(duì)業(yè)務(wù)方代碼無侵入
3.2 中間件
- NSQ:通過 NSQMessage 中添加 jsonExtHeader 的 KV 拓展信息煮纵,讓消息可以從 Producer 透?jìng)鞯?Consumer 端沉删,具體表現(xiàn)形式為:Key:zan_test;Value:true
- Wagon:對(duì)來自影子庫的 binlog 通過拓展消息命令(PUB_EXT)帶上壓測(cè)標(biāo)記{"zan_test": true}
3.3 異步線程
異步調(diào)用標(biāo)識(shí)透?jìng)鲉栴},可以自行定制 Runnable 或者定制線程池再或者業(yè)務(wù)方自行定制實(shí)現(xiàn)醉途。
四、數(shù)據(jù)隔離
通過流量識(shí)別的改造砖茸,各個(gè)服務(wù)都已經(jīng)能夠識(shí)別出壓測(cè)的請(qǐng)求流量了隘擎,那么如何做到壓測(cè)數(shù)據(jù)不污染線上數(shù)據(jù),對(duì)于不同的存儲(chǔ)做到壓測(cè)數(shù)據(jù)和真實(shí)的隔離呢凉夯,有贊主要有客戶端 Client 和 Proxy 訪問代理的方式實(shí)現(xiàn)货葬,下面就看一下有贊的數(shù)據(jù)隔離方案:
4.1 Proxy 訪問代理隔離
針對(duì)業(yè)務(wù)方和數(shù)據(jù)存儲(chǔ)服務(wù)間已有Proxy代理的情況采幌,可以直接升級(jí) Proxy 層,存儲(chǔ)使用方完全無感知震桶,無侵入休傍,下面以 MySQL 為例,說明 Proxy 訪問代理對(duì)于壓測(cè)數(shù)據(jù)隔離的方案蹲姐;
業(yè)務(wù)方應(yīng)用讀寫DB時(shí)磨取,統(tǒng)一與 RDS-Proxy (介于 MySQL 服務(wù)器與 MySQLClient 之間的中間件)交互,調(diào)用 RDS-Proxy 時(shí)會(huì)透?jìng)鲏簻y(cè)的標(biāo)記柴墩,RDS 識(shí)別出壓測(cè)請(qǐng)求后忙厌,讀寫 DB 表時(shí),自動(dòng)替換成對(duì)應(yīng)的影子表江咳,達(dá)到壓測(cè)數(shù)據(jù)和真實(shí)的生產(chǎn)數(shù)據(jù)隔離的目的
ElasticSearch逢净、KV 對(duì)于壓測(cè)的支持也是通過 Proxy 訪問代理的方式實(shí)現(xiàn)的
4.2 客戶端SDK隔離
業(yè)務(wù)應(yīng)用通過Client調(diào)用存儲(chǔ)服務(wù)時(shí),Client 會(huì)識(shí)別出壓測(cè)的流量歼指,將需要讀寫的 Table 自動(dòng)替換為影子表爹土,這樣就可以達(dá)到影子流量,讀寫到影子存儲(chǔ)的目的踩身;
Hbase胀茵、Redis 等采用此方案實(shí)現(xiàn)
4.3 數(shù)據(jù)偏移隔離
推動(dòng)框架、中間件升級(jí)惰赋、業(yè)務(wù)方改造宰掉,難免會(huì)有遺漏之處,所以有贊對(duì)于壓測(cè)的數(shù)據(jù)統(tǒng)一做了偏移赁濒,確保買賣家 ID 與線上已有數(shù)據(jù)隔離開轨奄,這樣即使壓測(cè)數(shù)據(jù)由于某種原因?qū)懭肓苏鎸?shí)的生產(chǎn)庫,也不會(huì)影響到線上買賣家相關(guān)的數(shù)據(jù)拒炎,讓用戶無感知挪拟;
這里要說一下特殊的周期掃表應(yīng)用的改造,周期性掃表應(yīng)用由于沒有外部觸發(fā)击你,所有無法掃描影子表的數(shù)據(jù)玉组,如何讓這樣的 job 集群整體來看既掃描生產(chǎn)庫,也掃描影子庫呢丁侄?
有贊的解決思路是惯雳,部署一些新的 job 實(shí)例,它們只掃描影子庫鸿摇,消息處理邏輯不變石景;老的 job 實(shí)例保持不變(只掃生產(chǎn)庫)
五、壓測(cè)平臺(tái)
有贊的全鏈路壓測(cè)平臺(tái)目前主要負(fù)責(zé)壓測(cè)腳本管理、壓測(cè)數(shù)據(jù)集管理潮孽、壓測(cè) job 管理和調(diào)度等揪荣,后續(xù)會(huì)有重點(diǎn)介紹,這里不做深入
壓測(cè)的“硬件”設(shè)施基本已經(jīng)齊全往史,下面介紹一下有贊全鏈路壓測(cè)的具體實(shí)施流程吧
六仗颈、壓測(cè)實(shí)施流程
廢話不多說,直接上圖:
有贊全鏈路壓測(cè)的執(zhí)行流程如上圖所示椎例,下面具體看一下幾個(gè)核心步驟在有贊是怎么做的挨决。
6.1 壓測(cè)計(jì)劃制定
要想模擬大促時(shí)線上真實(shí)的流量情況,首先需要確認(rèn)的就是壓測(cè)場(chǎng)景粟矿、鏈路凰棉,壓測(cè)的目錄,以及壓測(cè)的流量漏斗模型:
- 壓測(cè)的鏈路:根據(jù)公司具體業(yè)務(wù)具體分析陌粹,有贊屬于電商類型公司撒犀,大促時(shí)候的峰值流量基本都是由于買家的購買行為導(dǎo)致的,從宏觀上看掏秩,這樣的購買行為主要是店鋪首頁-商品詳情頁-下單-支付-支付成功或舞,我們把這一條骨干的鏈路稱為核心鏈路,其實(shí)大促時(shí)主要就是保證核心鏈路的穩(wěn)定性
- 壓測(cè)鏈路的漏斗模型:線上真實(shí)的場(chǎng)景案例是蒙幻,100個(gè)人進(jìn)入了商家的店鋪首頁映凳,可能有50個(gè)人直接退出了,有50個(gè)人最終點(diǎn)擊進(jìn)入了商品詳情頁面邮破,最終只有10個(gè)人下了單诈豌,5個(gè)人真正付款了,這就是壓測(cè)鏈路的漏斗模型抒和,也就是不同的接口的真實(shí)調(diào)用比例矫渔;實(shí)際的模型制定會(huì)根據(jù)近7天線上真實(shí)用戶的行為數(shù)據(jù)分型分析建模,以及往期同類型活動(dòng)線上的流量分布情況摧莽,構(gòu)建壓測(cè)鏈路的漏斗模型
- 壓測(cè)的場(chǎng)景:根據(jù)運(yùn)營報(bào)備的商家大促活動(dòng)的計(jì)劃庙洼,制定大促的壓測(cè)場(chǎng)景(比如秒殺、抽獎(jiǎng)等)镊辕,再結(jié)合近七天線上流量的場(chǎng)景情況油够,綜合確定壓測(cè)的場(chǎng)景;
- 壓測(cè)目標(biāo):根據(jù)運(yùn)營報(bào)備的商家大促預(yù)估的PV和轉(zhuǎn)換率情況征懈,結(jié)合去年同期線上流量情況和公司業(yè)務(wù)的增長速率石咬,取大值作為壓測(cè)的目標(biāo)
6.2 數(shù)據(jù)工廠
前面我們已經(jīng)介紹了如何確定壓測(cè)的目標(biāo)、場(chǎng)景卖哎、鏈路鬼悠,那么壓測(cè)的數(shù)據(jù)怎么來尼虏束,這就是數(shù)據(jù)工廠登場(chǎng)的時(shí)候了,下面就介紹一下有贊壓測(cè)的數(shù)據(jù)工廠
有贊的壓測(cè)數(shù)據(jù)工廠主要負(fù)責(zé)厦章,壓測(cè)鋪底數(shù)據(jù)的準(zhǔn)備、壓測(cè)請(qǐng)求數(shù)據(jù)塊的生成照藻;
6.3 鋪底數(shù)據(jù)準(zhǔn)備
壓測(cè)準(zhǔn)備鋪底的數(shù)據(jù)袜啃,這個(gè)眾所周知的,但是由于有贊壓測(cè)的方案采用的是影子庫的設(shè)計(jì)幸缕,所以對(duì)于鋪底數(shù)據(jù)準(zhǔn)備不得不去處理影子庫的數(shù)據(jù)群发。直接看下鋪底數(shù)據(jù)準(zhǔn)備的流程圖:
- 數(shù)據(jù)導(dǎo)入
從生產(chǎn)數(shù)據(jù)庫按需過濾,導(dǎo)入壓測(cè)鋪底需要的數(shù)據(jù)到大數(shù)據(jù)集群的hive表中发乔。 - 數(shù)據(jù)處理
在 hive 表中熟妓,對(duì)導(dǎo)入的數(shù)據(jù)進(jìn)行脫敏和清洗,清洗的目的是保證壓測(cè)的數(shù)據(jù)可用性栏尚,比如保證鋪底商品庫存最大起愈、營銷活動(dòng)時(shí)間無限、店鋪正常營業(yè)等译仗。 - 數(shù)據(jù)導(dǎo)出
對(duì) hive 標(biāo)中已經(jīng)處理完成的數(shù)據(jù)抬虽,導(dǎo)出到已經(jīng)創(chuàng)建好的影子庫中,需要注意的是同一實(shí)例寫入數(shù)據(jù)的控制(因?yàn)橛白訋旌蜕a(chǎn)庫同實(shí)例)纵菌,寫入數(shù)據(jù)的 binlog 過濾阐污。
有贊的壓測(cè)數(shù)據(jù)準(zhǔn)備目前全部在 DP 大數(shù)據(jù)平臺(tái)上操作,基本完成了數(shù)據(jù)準(zhǔn)備操作的自動(dòng)化咱圆,維護(hù)了近千的數(shù)據(jù)準(zhǔn)備 job
壓測(cè)請(qǐng)求數(shù)據(jù)數(shù)據(jù)集
gatling 原生支持 json笛辟、csv、DB 等方式的數(shù)據(jù)源載入序苏,我們采用的壓測(cè)數(shù)據(jù)源是 json 格式的手幢,那么如此海量的壓測(cè)源數(shù)據(jù),是通過什么方式生成和存儲(chǔ)的尼杠览,我們的實(shí)現(xiàn)還是依托于 DP 大數(shù)據(jù)平臺(tái)弯菊,通過 MapReduce 任務(wù)的方式,按需生成我們壓測(cè)請(qǐng)求需要的數(shù)據(jù)集:
- 從各個(gè)業(yè)務(wù)線的表中獲取壓測(cè)場(chǎng)景整個(gè)鏈路所以接口請(qǐng)求需要的參數(shù)字段踱阿,存到一張創(chuàng)建好的壓測(cè)數(shù)據(jù)源寬表中
- 編寫 MapReduce 任務(wù)代碼管钳,讀取壓測(cè)數(shù)據(jù)源寬表數(shù)據(jù),按壓測(cè)的接口請(qǐng)求參數(shù)情況软舌,生成目標(biāo) json 格式的壓測(cè)請(qǐng)求數(shù)據(jù)塊文件到 HDFS
- 壓測(cè)時(shí)才漆,壓測(cè)引擎自動(dòng)從 HDFS 上拉取壓測(cè)的請(qǐng)求數(shù)據(jù)塊
MapReduce 生成的數(shù)據(jù)集 json 示例:
6.4 壓測(cè)腳本準(zhǔn)備
6.4.1 梳理壓測(cè)請(qǐng)求和參數(shù)
壓測(cè)就要知道壓測(cè)的具體接口和接口參數(shù),所以我們采用統(tǒng)一的 RESTful 風(fēng)格規(guī)范佛点,讓各個(gè)業(yè)務(wù)方的人員提交壓測(cè)接口的 API 文檔醇滥,這樣壓測(cè)腳本編寫人員就能根據(jù)這份 API 快速寫出壓測(cè)的腳本黎比,以及接口的預(yù)期結(jié)果等
6.4.2 控制漏斗轉(zhuǎn)化率
有贊的壓測(cè)引擎用的是公司二次封裝的 gatling,原生就支持漏斗比例的控制鸳玩,直接看例子
6.4.3 不同場(chǎng)景的配比
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)
)
對(duì)不同的壓測(cè)場(chǎng)景鏈路按模塊編寫壓測(cè)腳本阅虫,這樣的好處就是需要不同場(chǎng)景混合壓測(cè)時(shí),只需要在 setUp 時(shí)不跟,按需把不同的場(chǎng)景組合到一起即可颓帝;需要單獨(dú)壓測(cè)某一個(gè)場(chǎng)景時(shí),setUp 中只留一個(gè)場(chǎng)景就好窝革,做到一次編寫购城,處處可壓。
6.5 壓測(cè)執(zhí)行
壓測(cè)的鋪底數(shù)據(jù)虐译、壓測(cè)腳本瘪板、壓測(cè)請(qǐng)求的數(shù)據(jù)集都已經(jīng)介紹完了,可謂是萬事俱備只欠東風(fēng)漆诽,那這個(gè)東風(fēng)就是我們自建的壓測(cè)平臺(tái) maxim侮攀,這里不對(duì)壓測(cè)平臺(tái)的設(shè)計(jì)展開介紹,展示一下 maxim 在壓測(cè)執(zhí)行過程中所承擔(dān)的工作拴泌。
maxim平臺(tái)主要的功能模塊有:
- 測(cè)試腳本:負(fù)責(zé)測(cè)試腳本的管理
- 數(shù)據(jù)集:負(fù)責(zé)壓測(cè)請(qǐng)求數(shù)據(jù)集的管理魏身,目前主要有兩種數(shù)據(jù)集上傳模式:直接上傳數(shù)據(jù)包和 hadoop 集群數(shù)據(jù)源路徑上傳。第二種上傳模式蚪腐,只需要填寫數(shù)據(jù)源所在的 hadoop 集群的路徑箭昵,maxim 平臺(tái)會(huì)自動(dòng)去所在路徑獲取壓測(cè)數(shù)據(jù)集文件
- 測(cè)試 job:負(fù)責(zé)測(cè)試任務(wù)的管理,指定壓測(cè) job 的腳本和腳本入口回季,以及壓測(cè)數(shù)據(jù)集等
- 壓測(cè)注入器:負(fù)責(zé)展示壓測(cè)注入機(jī)器的相關(guān)信息
- 壓測(cè)報(bào)告生成:壓測(cè)報(bào)告的生成家制,直接用的 gatling 原生的報(bào)告生成功能
maxim 平臺(tái)壓測(cè)結(jié)果報(bào)告
下面看一下壓測(cè)執(zhí)行的頁面功能:
- 壓力注入器數(shù)量:指定本次壓測(cè)執(zhí)行,需要多少臺(tái)壓測(cè)機(jī)去執(zhí)行
- 重復(fù)場(chǎng)景測(cè)試:一個(gè)虛擬用戶重復(fù)幾次壓測(cè)場(chǎng)景
- 并發(fā)用戶數(shù):可執(zhí)行壓測(cè)時(shí)泡一,按需填寫需要的每秒加載的并發(fā)用戶數(shù)和持續(xù)時(shí)間颤殴,無需每次變更壓測(cè)腳本
- 目標(biāo) RPS:可執(zhí)行壓測(cè)時(shí),按需填寫壓測(cè)的目標(biāo) RPS鼻忠,爬坡時(shí)間涵但,目標(biāo)持續(xù)時(shí)間,達(dá)到限流的作用帖蔓,可同時(shí)指定多個(gè)目標(biāo) RPS矮瘟,達(dá)到分梯度壓測(cè)的目的;
七塑娇、最后
到這里有贊全鏈路壓測(cè)方案已經(jīng)介紹完了澈侠,因?yàn)槠脑蜻€有很多實(shí)施細(xì)節(jié)部分并沒有完整表述,同時(shí)有贊的全鏈路壓測(cè)也才初具雛形埋酬,歡迎有興趣的同學(xué)聯(lián)系我們一起探討哨啃,有表述錯(cuò)誤的地方也歡迎大家聯(lián)系我們糾正烧栋。