[jvm-sandbox-repeater 學習筆記][原理說明篇] 1 錄製流程

ELes發表於2019-10-22

repeater系列學習筆記進入第二部分,原理說明篇。

本篇章會結合錄製回放的流程進行原始碼的導讀,並且附上我的學習解析,可能有講得不對、不夠好的地方,歡迎大家留言指正~

jvm-sandbox-repeater 學習筆記系列的文章建議按照順序閱讀~附上前序篇章:入門使用篇的傳送門

1.1 錄製流程圖

如下圖,描述了使用者觸發請求,當sandbox感知到呼叫事件到錄製結果儲存的過程。

錄製流程圖

1.2 錄製過程步驟的原始碼解析

在整個錄製過程中,repeater進行錄製的處理流程是DefaultEventListener類中實現。

接下來我們將以這個類作為入口去了解錄製過程的處理邏輯。

1.2.1 DefaultEventListener類

DefaultEventListener實現了sandbox的EventListener介面,是用來處理觸發事件的類。

在repeater中,不同的外掛可以自定義自己的EventListener來進行各自特殊的事件處理。而在當前的程式碼中,除了http外掛,其他外掛都使用的是預設的DefaultEventListener

DefaultEventListener中,承接的是所有事件的處理,也就是說無論是錄製操作,還是回放操作,都是集中在這個類中實現的,只是根據不同的條件來區分是錄製流量還是回放流量,從而判斷該執行錄製還是該執行回放。

在上面的流程圖中,repeater中的流程執行,實際上是DefaultEventListeneronEvent的流程圖。接下來我們一個一個流程去解析錄製過程的實現。

1.2.2 事件過濾

在整個事件處理過程中,總共經歷了兩個階段,四個事件過濾。

過濾順序 過濾說明 實現方法
1 針對單個listener,只處理top的事件
不同的外掛之間的listener相互隔離,所以即使是錄製http的請求,java子呼叫外掛的事件也能通過過濾。
DefaultEventListener.isTopEvent
2 進行基礎過濾,主要根據系統熔斷、降級進行判斷。該過濾條件與repeaterConfig中的degrade欄位、exceptionThreshold欄位有關。 DefaultEventListener.access
3 執行取樣計算(只有entrance外掛負責計算取樣,子呼叫外掛不計算),該過濾條件與repeaterConfig中的sample欄位有關。 DefaultEventListener.sample
4 判斷是否是外掛呼叫處理器設定為忽略的事件。每個外掛處理不同。 processor != null && processor.ignoreEvent((InvokeEvent)event)

1.2.3 初始化跟蹤器

當事件通過第一個過濾時,就會進行跟蹤器初始化。

/**
* 初始化上下文;
* 只有entrance外掛負責初始化和清理上下文
* 子呼叫無需關心traceContext資訊(多執行緒情況下由ttl負責copy和restore,單執行緒由entrance負責管理)
*
* @param event 事件
*/

protected void initContext(Event event) {
if (entrance && isEntranceBegin(event)) {
Tracer.start();
}
}

跟蹤器相關的內容在com.alibaba.jvm.sandbox.repeater.plugin.core.trace包中。

其中我們提到的traceId實際上是這個跟蹤器的獨立標識。所以無論是錄製和回放都會有其獨立的traceId。

1.2.4 Before事件處理

對應的方法是DefaultEventListener.doBefore

  1. 判斷當前流量是否為回放流量,若為回放流量則呼叫processor.doMock方法執行Mock,不執行後續操作。

  2. 若當前流量非回放流量,則基於當前獲取到的資訊拼接Invocation例項。其中會呼叫外掛呼叫處理器的assembleRequest、assembleResponse、assembleThrowable、assembleIdentity方法進行請求引數、返回結果、丟擲異常、呼叫標識的拼接。

  3. 根據外掛呼叫處理器的設定,判斷是否需要進行Invocation中的request、response、throwable引數的序列化。

  4. 將當前事件的Invocation資訊存放到錄製快取中。

1.2.5 Return事件處理/ Throw事件處理

return事件與throw事件的處理邏輯基本一致。

  1. 判斷當前流量是否為回放流量,若為回放流量則不執行後續操作。

  2. 從錄製快取中獲取對應的Invocation例項,如果獲取失敗則列印失敗日誌,不執行後續操作

  3. Invocation例項獲取成功後,呼叫外掛呼叫處理器的assembleResponse或者assembleThrowable方法將reponse或者throwable資訊設定到Invocation例項中。並設定Invocation的結束時間。

  4. 回撥呼叫監聽器InvocationListeneronInvocation方法,判斷Invocation是否是一個入口呼叫,如果是則呼叫訊息投遞器的broadcastRecord將錄製記錄序列化後上傳給repeater-console。如果不是則當做子呼叫儲存到錄製快取中。

PS:訊息投遞器當前支援兩種模式,在standalone模式下,儲存到本地檔案;在非standalone模式下上傳到repeater-console。

相關文章