如何讓線上錄製回放落地的具體思路

moku發表於2020-10-16

背景

這幾天看到 @ShaoNianyr 提出了一個思路,就是對專案進行流量錄製和回放
通過錄制+回放的方式,在每次測試新功能的時候就可以只關心如何測好新的介面和如何迴歸無法錄製的介面,甚至可以減少大部分功能的自動化測試程式碼
不過在當前的討論中,發現實際操作的時候,本質上沒有和尋常的介面測試/壓測有太多區別,且落地上會存在一些問題

落地的難點

  1. 如果只是錄製+回放,那麼介面的對錯是不能判斷的,所以需要引入diff,然後如果要加入diff的話,有一個問題是無法避開的,如何保證線上的資料能線上下使用?
  2. 錄製的時候如果遇到了修改資料庫操作的請求,怎麼處理?
  3. 錄製應該有時限,我們是否應該按照版本進行錄製?如果按照版本進行,那如何處理老的流量?

我和 @ShaoNianyr 的解決思路

首先思考到的方式是:

  1. 把diff的目的改為:找到返回一致的介面,把線上的請求帶的引數通過文中例子說的規則匹配轉換為可以線上下用的引數,對比沒有出問題的介面

  2. 在程式碼層面增加一個fake中介軟體的邏輯,如果我們是在進行流量回放(比如通過header帶一個引數做判斷),那麼連線的就是一個假的中介軟體,這裡以mysql舉例,這個中介軟體的作用是把錄製時間段內的sql操作,sql的返回結果進行記錄,並一一對應hash處理,當這個服務被其他服務呼叫且傳過來了sql,就返回線上資料庫裡這個sql的查詢結果。這樣的好處是把最頂層(流量),最底層(中介軟體返回的結果)都進行了一次錄製,相同的請求,相同的中介軟體查詢,這樣不同環境下介面的迴歸和diff如果出現了問題,那就說明這個介面發生了變化,達到了我們進行diff的目的,簡單說,就是中介軟體的mock

再次遇到了問題

對於第一個方案,如果線上線下資料差異過大,把http請求帶的在test環境找不到的引數都轉為一個,或者一部分特定值,那麼這個介面的返回和線上介面的返回不一致的可能就是很大的,如果流量很多,我們沒觸發diff的介面就會遠遠少於觸發diff的介面,如果這個時候去把那些觸發diff的結果都看一遍,那會是一個工作量特別大的事情

對於第二個方案,等於我們需要去根據中介軟體的介面重寫一份我們的fake介面,同時也會修改到業務程式碼,時間成本是巨大的,同時測試團隊目前也沒有這個技術資源

新的思路

那我們能不能找到一個不需要改業務程式碼,能用到線上流量的方案呢?

有的,就是有點粗暴

流程如下(僅只迴歸測試,新功能測試還是需要自己來哈)

這個過程中的diff也不是傳統的diff,沒有進行2次請求自動降噪,而是直接對比,噪音資料人工配置規則進行過濾(這個是根據當前我們的業務來的,介面中不存在太多噪音,也有考慮再多一個環境的成本問題)

是不是漏了一個東西?

上面一直沒有提到老版本流量的處理,因為事情按照優先順序來嘛,處理好了錄製+回放才到這步

針對老的流量,可以在test環境進行回放時,去獲取到當前流量的覆蓋率(goc/jacoco+sonar),和上一個版本的覆蓋率情況做對比,找到覆蓋率有差異的資料,人工分析整理到一個精華測例集裡面(自動化程式碼或者流量檔案形式都可以)

在去年MTSC大會上,平安證券也分享過如何對線上的流量資料進行分析和留存的思路(平安證券-基於生產日誌的介面用例設計與優化)

補充

這裡提了兩個解決 回放流量時候 線上資料庫 和 測試資料庫 不一致差異問題 的方案:

  1. fake 方案: 程式碼層實現 fakeDB 以及 fakeInterface ,對標記 fake 流量的相同 sql 查詢,走 fakeDB,返回相同的 response,直接解決資料差異的問題。

    - 優點: 流量拿來就用,加上 fake 標記即可回放。

    - 缺點: 需要改程式碼,需要對不同中介軟體介面實現fake介面

  2. test-prod 方案: 底層實現測試環境對接線上影子庫,用線上流量日誌回放 stage 以及 test-prod

    - 優點: 不用改業務程式碼。

    - 缺點: 需要實現快照恢復和一鍵切換到影子庫。

    test-prod 方案實施仍需解決的問題:

    - 快照資料庫好解決,中介軟體資料的快取如何快照恢復?

    - 涉及儲存的業務,在回放前,需要獲取線上儲存的快照資料,並同步到測試儲存環境中。

    - 需要統一日誌格式,按日誌格式實現一個請求模擬伺服器,並實現轉發前後業務邏輯替換規則。

目前只打算從僅和mysql相關的業務進行推動,落地之後逐步解決問題(有資源後會考慮去實現第一個的fake方案)

相關文章