第一次聽到埋點這名詞的時候,是在三年前,剛進某會時。
隨后一直接觸相關埋點需求的開發,然而,卻一直沒有好好的研究過。
最近,新公司需要埋點的實現方案。也就有了研究的機緣。
回想了前公司大神的實現方案,由于業務復雜,相關角色也錯綜復雜。起初美好的愿景變得慘不忍睹。該死的業務!
整理了下,我想,起初的愿景應該是醬紫的。
以下純粹為了記錄,水平不高,各路大神路過輕噴。
有以下三個角色:
Sender,專職發送埋點的。
Recorder,專職記錄埋點的。
Reader,專職讀取埋點的。
而這些角色之間的協作方案,就是埋點的實現方案。
主要采用了 Service + HandlerThread 的實現方式。(參考了前公司大神的實現方案)
由于 HandlerThread 持有 Loop 對象,并開啟了消息循環。所以用其作為埋點事件(記錄/發送)的隊列管理。
再通過HandlerThread 創建 Handler 對象,用于向 HandlerThread 發送消息。
如下圖,埋點記錄的時序圖:(Recorder 持有 RecorderHandlerThread 的 Handler 對象
當調用方Cp 埋點類 post 一個埋點信息(logData)時,Recorder 會調用 record() 方法,將 操作數據庫保存埋點信息的動作 包裝成線程,并通過Hander 向RecorderHandlerThread 發送該消息。
RecorderHandlerThread 收到消息后,執行保存埋點信息的動作。
再如下圖,埋點發送的時序圖:(Sender 持有 SenderHandlerThread 的 Handler 對象)
ReaderThread 循環向 Db 獲取埋點信息(logData),當不為空時,Sender 會調用 send() 方法,將 埋點信息發送的動作 包裝成線程,并向SenderHandlerThread 發送該消息。
SenderHandlerThread 收到消息后,便執行發送埋點信息的動作。
具體的類圖如下:結合上面的時序圖,可以清楚的看出各類之間的關系。
LogServiceV2:
繼承Service,各線程寄托于Service 里,提高優先級,延長其生命周期,避免內存不足時誤殺。
當LogServiceV2 啟動后,RecorderHandlerThread,SenderHandlerThread 便開始等待消息并執行。ReaderThread 便循環的讀取數據存儲的最新埋點信息。
Recorder :
埋點記錄者,持有RecorderHandlerThread 的 Handler 對象,通過handler對象,可向 RecorderHandlerThread 發送消息。
Sender :
埋點發送者,持有SenderHandlerThread 的 Handler 對象,通過handler對象,可向SenderHandlerThread 發送消息。
ReaderThread:
埋點讀取者,循環向 數據存儲 讀取最新的埋點。
好久沒寫技術文檔。回看一遍,還是太粗糙了。感覺還是貼代碼會更加清晰點。囧。
下一篇貼下部分源代碼繼續介紹。