[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。

相關文章