流量回放开源代码Java_流量回放框架 jvm-sandbox-repeater 的实践
一. 前言
你是否和我一樣遇到過以下的問題?
1)服務重構,一堆接口需要回歸,讓人頭疼
2)每次迭代,都要花很多精力來進行回歸測試
3)線上 bug,線下復現不了
4)接口自動化用例寫辛苦,維護更辛苦
… …
或者許你正在被這些問題困擾。你可能和我一樣也嘗試過一些流量回放工具來解決上述問題,但最終經歷了從入門到放棄的無奈。現有大部分流量回放工具中都存在這樣那樣的限制,比如只支持 GET 接口、不能對子調用進行 mock、對環境和數據依賴高等,所以往往線上錄制時心驚膽戰,線下回放時坎坷不斷。回歸的接口少,使用流量回放還不如手動測試快。回歸的接口多,使用的坎坷讓人絕望。
所以我們需要的是一款簡單易用、安全可靠的流量錄制回放工具!!!
在此,推薦 jvm-sandbox-repeater。
二. jvm-sandbox-repeater 簡介
jvm-sandbox-repeater 是阿里在 19 年 7 月份的時候開源的流量錄制回放工具,代碼提供了錄制回放的能力,以及一個簡單的 repeater-console 的 demo 示例。github 地址:https://github.com/alibaba/jvm-sandbox-repeater。
jvm-sandbox-repeater 框架基于 JVM-Sandbox,具備了 JVM-Sandbox 的所有特點封裝了以下能力:
1.錄制/回放基礎協議,可快速配置/編碼實現一類中間件的錄制/回放
2.開放數據上報,對于錄制結果可上報到自己的服務端,進行監控、回歸、問題排查等上層平臺搭建
基于它,我們可以在業務系統無感知的情況下,快速擴展 api ,實現自己的插件,對流量進行錄制,入口請求(HTTP/Dubbo/Java)流量回放、子調用(Java/Dubbo)返回值 Mock 能力。詳細介紹可以看官方說明。
錄制回放主要原理如下:
錄制:如圖,當 repeater 啟動對 service A 的錄制后,有請求到 service A,sandbox 感知到請求后通知 repeater。repeater 對事件進行過濾和采樣計算,對滿足錄制條件的請求會記錄請求、響應、子調用和響應,序列化成后通知 repeater-console 進行處理和保存。
回放:回放時,用戶請求 repeater-console 的回放接口,明確需要回放哪條錄制數據。然后 repeater-console 通過調用 repeater 提供的回放任務接收接口下發回放任務。repeater 在執行回放任務的過程中,會反序列化記錄的 wrapperRecord,根據信息構造相同的請求,對被掛載的任務進行請求,并跟蹤回放請求的處理流程,以便記錄回放結果以及執行 mock 動作。如圖,當我們啟用了 redis 插件,錄制時,service A 到 reids 等的子請求方法、參數、響應將被錄制下來,回放時,當 service A 再對 reids 發起請求時,repeater 會先判斷是否需要 mock,當需要 mock 時會根據回放上下文中的信息拼接出 MockRequest,通過 mock 策略計算獲取 MockResponse。目前源碼中是獲取相似度 100% 的請求的響應來進行 mock。回放結束,repeater 會將回放信息和結果序列化后通知 repeater-console 進行處理和保存。
進一步了解可以閱讀源代碼或者參考大能文檔:
三. 我們的落地實踐
jvm-sandbox-repeater 僅僅提供了錄制回放的能力,如果真的需要實現業務回歸使用,后面須要有一個數據中心負責采集數據的加工、存儲、搜索。repeater-console 提供了簡單的 demo 示例,它支持本地或者 mysql 存儲和獲取錄制回訪結果,可進行單請求的錄制回放,使用可參考官方文檔。而真實的使用場景中,我們一般需要的是批量的錄制、回放以及結果查看,所以需要寫一個自己的 repeater-console,另外也還需要實現更多的 repeater-plugins。官方已經有了一些常用的插件,所以我們根據需要,從沒有的入手。主要改動有:
1)根據需要,先實現了 SOA、mongo 和 es 插件,后續還需要慢慢加。框架封裝了基礎錄制回放協議,對于普通插件開發可以快速完成,主要成本在于尋找最合適的插樁埋點
2)將錄制、回放都結果存入 es,并增加了一些字段方便數據搜索查詢。
3)在 RecordFacadeApi.java 中增加了批量獲取錄制結果、批量回放、批量獲取回放結果接口。
4)console 獨立部署,配置獲取接口/facade/api/config/%s/%s 從數據庫獲取配置,大大減少了對目標服務器資源的占用。
5)repeat 接口支持 diff,diff 結果也存入 es。回放結果查詢時,支持 diff 過濾。
四.結果展示
完成上述改造,基本上流量回放就可以簡單使用起來了。下面記錄一次錄制回訪的過程。
1)在目標服務器上運行./sandbox.sh -p {PID} -P 12580 啟動錄制,看日志見插件加載成功,服務開始錄制
2)批量查看錄制結果
3)批量回放。
一般我們錄制和回放的服務器不是同一臺,且 console 獨立部署了,所以這里需要指定期望回放到哪一臺服務器。
另外為了滿足只回放某個接口的請求,我們對 batchGethe 和 batchRepeat 接口也增加了對指定接口的支持。
4)批量回放結果查看
在回放結果入庫時,我們對 originResponse 和 response 進行了 diff,和回放結果一起存入 es。這樣就可以指定只看回放成功或者失敗的用例。下面這條是回放成功的,可以看到 diff 為 false,diffReseult 為 null。
增加了請求接口信息 requestApi,方便知道是哪個接口的回放。response 是回放求結果,originResponse 是錄制的原始響應,可以看出來結果一致。mockInvocationEsLists 是 mock 的插件方法和參數。
當想獲得比對失敗回放時,參數 diff 傳 0,結果如下
5)資源占用情況
在服務器上的錄制。啟動 repeater 開始錄制,約占用 80M 的內存。另外短時間也會有較大的 cpu 開銷,因為需要遍歷所有加載的類以及類增強。而和 console 交互也會占用部分網速,可能影響響應時長。所以線上錄制時,務必預留好資源。
回放時,一般建議在線下回放。批量回放對 cpu 資源占用較高,這個后續優化。
五.坑和注意點
由于 jvm-sandbox-repeater 剛開源不久,使用時一些坑或者注意點需要了解下。沒有詳細記錄,這里摘要幾點。
1)服務要求至少 2 個 CPU,ThreadPoolExecutor 中有限制,單核會初始化線程池失敗。使用前需要檢查下服務器的配置。
2)當 post 請求同時包含 params 和 body 時,代碼會只處理 body 忽略 params,導致接口回放響應失敗。源代碼 invokePost 函數中處理 post 請求時,body 中沒有數據,就取 paramsMap 組裝成 FormBody 去執行;如果 body 不為空,就調用 invokePostBody(url, headers, body),把 paramsMap 給丟了。這邊簡單兼容了下兩者并存的情況。
3)官方開源代碼的 HttpUtil 基于 okhttp3.OkHttpClient 封裝的 http 請求工具中,只支持 GET 和 POST 方法,其他的方法回放時會報錯。這個估計是開發漏掉了,寫起來不難,照著 invokeGet 和 invokePost 的實現方法抄一份,請求方法稍微改下就行。
4)回放時,子調用會去匹配 mock 請求參數的相似度,取相似度 100% 的來 mock。如果子調用參數有當前時間相關的或者隨機數等,就會出現匹配不到的情況。這邊修改的邏輯是如果沒有相似度 100% 的,就取相似度最高且大于某個值的,否則 mock 失敗,拋出異常,阻斷流程。當然不是 100% 的匹配度,就可能出現返回不是正確響應的 mock 的情況。這個需要自己權衡。
5)repeater 不支持對 http 返回 code 的比對,只比對返回的 body。回放時對響應不是 2xx 的會給出異常提示而非原始響應,導致回放比對失敗,所以不支持對非 2xx 響應接口調用的回放使用。至于 httpCode 的比對,目前看上去是不支持的。
六.總結
jvm-sandbox-repeater 是一款便捷好用的流量回放工具。它無侵入、熱插拔的特點對于有一堆歷史服務的我們來說有著致命的吸引力。由于直接作用在 jvm 層,它的通用性和可擴展性都不錯。
下一步的計劃就是支持更多的插件,比如 kafka、es 等,然后平臺化,支持平臺操作配置變更、錄制、回放、結果查看、歷史記錄查看等。如此,我們就可以從回歸測試的漩渦中解脫出來了。
最后感謝阿里開源了這一個強大的流量回放工具。由于本人水平有限,文中對 repeater 認知有誤的歡迎指正。
關注我們
酷家樂質量效能團隊熱衷于技術的成長和分享,幾乎每個月都會舉辦技術分享活動(海星日),每半年舉辦一次技術專題競賽分享(火星日),并將優秀內容寫成技術文章。
我們盡可能保障分享到社區的內容,是我們用心編寫、精心挑選的優質文章。如果您想更全面地閱讀我們的文章,請您關注我們的微信公眾號"酷家樂技術質量"。
如果您有興趣了解我們的職位和團隊情況,請參考最新職位招聘,并聯系 caibao@qunhemail.com。感謝您的閱讀!
總結
以上是生活随笔為你收集整理的流量回放开源代码Java_流量回放框架 jvm-sandbox-repeater 的实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【TeeChart .NET教程】(七)
- 下一篇: 服务器返回值 解释 ajax提交方式