流量回放框架 jvm-sandbox-repeater 實踐二

酷家乐质量效能發表於2020-09-10

前文連結:流量回放框架 jvm-sandbox-repeater 的實踐

1.前言

前文中,我們已經介紹了jvm-sandbox-repeater的原理,以及我們對它的初步實踐。本文將進一步介紹我們目前的平臺化實踐工作。我們將該平臺稱為kurepeater。篇幅限制,這裡主要介紹下kurepeater的基本架構和錄製回放的優化設計。

2.基本架構

kurepeater主要由repeater(jvm-sandbox-repeater)、console、es、db、前臺頁面5部分組成。前端頁面結構參考了官方demon並結合實際需要進行設計,採用公司內部框架進行開發;後臺基於官方開原始碼,並進行一些定製化的改造。

前臺頁面只和console進行互動,console操控整個流程。各模組間互動關係如下圖所示。

要啟動repeater進行錄製時,需先從前臺進行配置和模組安裝。配置我們儲存在了DB裡面。模組安裝負責將jvm-sandbox-repeater安裝到目標伺服器上。點選啟用,啟動和錄製流程如下圖。錄製資料序列化後存入es。

錄製結束,可以在前臺選擇需要回放的流量和方式,通知console。後臺回放流程如下。

回放成功後,我們可以在前臺頁面檢視回放結果資料,成功失敗資訊,並對失敗介面進行排查。

3.錄製優化

平臺化後,使用kurepater平臺對流量進行錄製,特別是線上環境,遇到了如下兩個問題
1)有些介面不想錄制怎麼辦
2)線上各介面流量嚴重不均衡,高頻介面錄製了一堆,低頻介面可能一次都沒錄到
對於問題1,一開始我們在白名單httpEntrancePatterns裡面寫正則過濾這些介面,比如^ ((?!/error$)).*$,然後重新啟動服務。但是頻繁的修改httpEntrancePatterns和重啟服務比較麻煩,另外正則配置在辨識度和易用性上也存在一定的困難。為此,我們增加了黑名單blackEntrancePatterns過濾功能。與httpEntrancePatterns相對應,在blackEntrancePatterns中的介面都不錄製。blackEntrancePatterns優先順序高於httpEntrancePatterns。
對於問題2,其中一種解決辦法就是當某個介面錄製的量太大了,我們就把這個介面加進黑名單,然後重新啟用服務繼續錄製。如此迴圈,確保高頻介面量不至於太多,低頻介面也有錄製到。當要錄製的介面比較少時,這種方法還行。但當要錄製大量介面時,這種操作就有點繁瑣尷尬了,所以最好是一開始就根據不同的介面qps賦予介面級別取樣率。
為此,我們在官方實現的http外掛裡面加了點程式碼,大致如下

前端配置介面如下。第一個取樣率是統一的取樣率,供所有需要錄製但是沒有特別強調介面取樣率的介面使用。console裡面的配置讀存也做了修改。

4.回放優化

錄製流量後對流量進行回放,發現回放結果比對失敗的很多。經過對失敗原因進行排查和統計,發現有些是真的新程式碼有bug導致的失敗,但更多的失敗並不是程式碼bug,例如
1)程式碼修改,修改了子呼叫,導致mock失敗
2)有不支援的子呼叫,導致失敗
3)子呼叫有隨機引數相關,導致mock匹配不上
4)響應的內容用了隨機數或者時間相關引數,導致比對失敗
5)repeater程式碼缺陷
還有一些其它原因,這裡不一一贅述。失敗原因很多,真正有效的失敗數很少。如此一來,每次回放失敗的排查成本就非常高,這違背了我們的初衷,也給平臺的內部推廣帶來了困難。我們迫切期望過濾無效的失敗,節約不必要的排查時間。

4.1 diffy降噪

為了提高回放結果失敗的有效性,我們先嚐試了過濾欄位功能,diff校驗時對某些欄位不進行校驗。

這種方案對單介面回放測試時比較有效。但是他只針對上述常見失敗原因的第4條。而且如果想批量回歸某個服務的所有介面,加之服務介面增加和迭代,使用起來就會比較麻煩。我們還是需要一種可以智慧降噪的方式。為此我們使用了diffy工具來進行降噪。
diffy能夠通過比較candidate(候選版本)和primary(穩定版本)和secondary(穩定版本副本)的差異值來消除噪聲,得到最終的diff結果。原理如下圖,具體介紹網上很多,這裡不仔細介紹。

我們在diffy開原始碼的基礎上做了修改,提供瞭如下介面功能。如下圖,此時left傳的是回放目標服務的響應,right傳的是錄製服務的響應,right2傳的是降噪服務的響應。

可以看到,介面請求diffy告訴我們BCD三個欄位的響應值不同。其中C和D欄位noise為1,表示在降噪環境回放也是不對的,不具備比較和排查意義,只有B這個欄位需要排查。
所以假如我們線上上環境(prod)進行了流量錄製,欲要回放到開發環境(dev),不妨使用一個線下穩定環境(stable)進行降噪。將三個環境的響應值都呼叫diffy進行比對,如果最終diff結果都沒有差異,或者有差異的欄位noise都為1,就可以認為這條回放是成功的。

4.2 流量過濾

進一步考慮,既然我們需要回放到stable環境和dev環境,那麼我們可以在回放到stable的時候對流量就先進行一個過濾,對那些明確會回放失敗的流量我們就沒必要再回放到dev了,比如有暫不支援的外掛。這裡需要判斷怎樣的流量是沒有必要回放的,即無效流量。簡單邏輯如下

stable回放結果diff我們這裡依舊使用了官方的,欄位過濾邏輯保留。如果回放diff失敗了,且有子呼叫mock沒有兜住。那麼說明他的程式碼走了新的鏈路,或者子呼叫請求中有較多隨機數等。此時這些流量回放到dev去也難逃失敗的命運,所以可以過濾掉這部分流量。反之,則可將流量回放到dev去。

4.3 回放流程邏輯

基於以上diffy降噪和流量過濾,降噪回放整體流程設計如下圖所示

前端入口設計如下

kurepeater支援在前端選擇是否降噪。選擇降噪則進行流量過濾和diffy比較;選擇不降噪則走原邏輯,直接回放到目標服務,使用開原始碼自帶的diff工具進行比較。

4.4 效果資料

下面是我們某一次回放的實驗結果。如果我們選擇不降噪,那麼共回放了38500條,回放失敗249條。這樣回放排查的工作量是很大的。

選擇使用降噪功能後,經過濾能走到dev流量只剩約19870條,失敗只剩約120條,都少了約一半。排查的工作量依舊是很大的

降噪回放檢視結果時把diffy降噪判斷的開啟進行過濾,此時需要我們去仔細排查確認的只剩兩條,如此就比較輕鬆了。

5.總結:

kurepater平臺已經在公司內部開始推廣試用,目前已共在幾十個服務上進行了數千次回放,回放功能對部分服務程式碼的行覆蓋率已達到了40%以上。下一步,我們將考慮提升kurepeater平臺的易用性,比如增加更多的外掛支援,進一步優化介面取樣配置,優化問題的排查效率等。感興趣的可以一起討論和學習。

想了解更多關於酷家樂技術質量的文章,歡迎關注我們的公眾號

相關文章