
1.專案背景
目前常用的壓測工具一般都是針對QPS這一個單一指標進行考量,即使支持撰寫腳本的工具也只是通過引數化模擬用戶,但是實際用戶是使用單獨設備請求服務器,即一個用戶就是一個tcp連接,
所以為了更真實的模擬用戶行為,我們需要通過一個tcp連接模擬一個用戶,并通過代碼方式實作用戶的真實請求行為,C端及中臺產研中心云平臺部質量保障團隊自研的“仿真壓測系統”,獨有的QPS動態可控技術,支持固定URL壓測、引數化、Websocket協議壓測、中間件、資料庫等的壓測,模擬用戶真實軌跡,通過用戶側,服務端,DB進行資料一致性和正確性自動檢驗,打造真正的全鏈路仿真壓測,該系統可擴展性強,穩定性高,目前已多次支持公司級各類大型活動的仿真全鏈路壓測,為線上服務的穩定運行提供了強有力的質量保障,
經過四年的打磨如今借此機會與大家分享一下心路歷程,積極討論,歡迎提出意見,希望可以幫助我們進一步成長,(文中參考均為測驗資料)
2.仿真壓測系統成型之路
2.1
工具選型
? 2.1.1 現有的壓測工具對比

圖1-1
? 2.1.2 Locust發壓client比較

圖1-2
結合以上比較結果,目前沒有合適的壓測工具可以直接滿足我們的壓測需求,最終決定用Locust做框架,首先它是一款易于使用的分布式負載測驗工具,完全基于事件,單機并發能力高,并發機制是協程,其次二次開發潛力比較大,
發壓的請求client采用fasthttp, 據說是目前golang性能最好的http庫,原理是利用worker復用goroutine,減輕runtime調度協程的壓力,相對于自帶的net/http(每個連接都需要新建一個goroutine),性能有10倍的提升,省略一千字,直接上干貨,
? 2.1.3 仿真壓測系統特性:
-
分布式部署;
-
固定URL壓測;
-
引數化腳本壓測;
-
Websocket協議壓測;
-
其他協議UDP、http2、 RTMP/HLS、MQTT(golang可以實作的協議都可滿足)
-
Redis直壓;
-
Kafka直壓
-
Mysql直壓;
-
自定義腳本壓測(仿真壓測,全鏈路資料對賬);
-
動態可控QPS、TCP;
-
秒級啟動/停止,結果收集即停即展示,無需等待
……
? 2.1. 4 實作難點分析
模擬百萬用戶創建TCP/ websocket連接;長時間保持連接不斷開;集中發壓;
部分代碼如下:
go func() {
for {
select
case data := <-r.stats.messageToRunnerChan:
data["user_count"] = r.numClients
r.outputOnEevent(data)
case <-r.closeChan:
Events.Publish("boomer:quit")
r.stop()
wg.Done()
return
}
}
}()
集中發壓
curTime := myStatus.Ct
statusTime := myStatus.St
c := time.After(time.Duration(statusTime-curTime) * time.Second)
<-c
miaosha(uidToken, &myStatus, myLog)
保持長鏈接
func wsWorker() {
ws, err := websocket.Dial(wsUrl, "", origin)
if err != nil {
log.Println(err)
return
}
defer func() {
if p := recover(); p != nil {
log.Println(p)
}
erc := ws.Close()
if erc != nil {
log.Println(erc)
}
}()
go func() {
ws.Write([]byte("0"))
var t = time.Tick(time.Second * 30)
for range t {
if ws == nil {
continue
}
ws.Write([]byte("0"))
fmt.Println("send 0 to websocket ok!")
}
}()
for {
select {
case <-stopChannel:
return
default:
var msg = make([]byte, 512)
start := time.Now()
n, err := ws.Read(msg)
log.Println(string(msg[0:n]))
elapsed := time.Since(start)
if myDebug {
log.Println(string(msg))
}
if err != nil {
log.Printf("Error: %s", err.Error())
}
}
}
}
2.2
日常使用截圖

圖2-平臺首頁

圖3-實時監控壓測頁面,總請求數、實時qps、回應時間、發壓機cpu占用等指標,

圖4-壓測空介面,服務器監控截圖, Nginx的峰值QPS可以達到596萬,

圖5-壓測redis時監控截圖,單個節點的實時監控等都可以一覽無余
3. 818臺網實戰開始
工欲善其事,必先利其器,利器已有,劇本安排上,
晚會當天數以萬計的用戶通過手機app參與活動,從白天開始“預約紅包”,晚上八點晚會開始后用戶開始陸陸續續登錄app“領取預約紅包”;隨著主持人口播,第一輪“集卡”活動開始……人數慢慢增多,到了最激動人心的時候,“一元秒新車”開始,QPS狂飆,TCP連接數也達到了峰值100W,
開始實戰:
控制臺:各部門注意,入口已經放開,流量開始進入;目前“預約紅包”階段
仿真壓測:收到,每五分鐘遞增1w用戶(1TCP模擬1用戶以下通用TCP數代指用戶數),QPS200(用戶進入活動頁面,預約紅包、查看規則、查看介紹等大概每人5次請求)

控制臺:晚會開始,“預約紅包”可領狀態,“見面禮紅包”已開啟,“連續紅包”已開啟,第一場大咖講話馬上開啟……
仿真壓測:明白,TCP調整到20W,QPS2W(用戶操作5次集中在1分鐘以內)

圖7-動態調整QPS、TCP連接數按鈕

圖8-設定TCP連接數、QPS、步增等

圖9-設定生效,TCP、QPS穩定保持在設定值
控制臺:抽盲盒活動進入倒計時
仿真壓測:copy,TCP調整到30W,QPS10W(用戶3秒內點擊10~15次提交一次請求到服務器)

圖10-設定生效,TCP、QPS穩定保持在設定值
控制臺:時間來到最侄訓節,“一元秒新車”,倒計時開啟
仿真壓測:拼手速的時候到了,TCP100W,QPS100W(秒殺只可以提交一次)走起

圖11-設定生效,TCP、QPS穩定保持在設定值
至此,晚會結束,仿真壓測卻并沒有結束,還有最后一環--“對賬”,仿真壓測會把介面回傳用戶的資料記錄到kafka中,最后入庫,與服務器的資料進行對賬,確保每條資料的正確性,

圖12-服務側資料與用戶側資料進行對賬
看一下動態調整QPS的完美曲線,隨著用戶增長以及QPS增長的仿真圖

圖13-仿真模擬用戶遞增的曲線

圖14-服務器監控截圖,仿真用戶全部走websocket協議,通過“狀態機”下發指令、接收指令

圖15-Redis 監控截圖

圖16-云服務器LB截圖

圖17-云服務器LB截圖

圖18-云服務器LB截圖

圖19-仿真壓測完成,服務側獎品發放明細

資料完美對上,
4. 總結
由于篇幅受限,想說的很多,質量保障團隊也做了很多,比如災備演練,模擬服務器滿載、域名切換、服務器宕機、機房切換等等,關于測驗方面的問題歡迎私下討論,
作者|劉建宇
本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/Full-link-simulation-pressure-testing-system.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/549408.html
標籤:其他
上一篇:應急回應
