1. 程式人生 > 其它 >日誌客戶端設計問題

日誌客戶端設計問題

前段時間在做應用db訪問日誌客戶端的開發,這裡記錄下日誌客戶端設計相關問題:

1. 如何攔截請求?

a. 公司的db訪問都是統一經過dal框架,所以動態給dal框架底層執行方法增加攔截程式碼即可。主要思路是在註冊tomcat啟動監聽,在監聽程式碼中,註冊jvm修改類定義的tranform(參考jvm的instrument功能),最後使用asm修改dal程式碼,增加攔截記錄日誌程式碼。這樣客戶端無需做改動。

b. 使用jvm-sandbox框架,jvm-sandbox底層也是使用方法a的原理。

差別:

方法a需要在應用程式碼里加入記錄日誌程式碼依賴。具體是在pom增加dependency,方法b不需要在應用程式碼里加,但是需要在應用的應用伺服器上啟動jvm-sandbox程序。

最終選型:

日誌記錄端使用方法a,原因是使用方法b對開發者透明,不容易管理。我們還有給記錄的日誌進行流量回放的功能,在流量回放的時候使用了方法b,因為流量回放只會在測試環境做,所以管理問題沒有那麼嚴重,而且回放使用方法b還有個好處就是動態插拔,jvm-sandbox可以只在測試環境部署。

下面從方法a來講解客戶端設計需要注意的地方:

1. 如何控制IO?

日誌記錄是IO密集型,我們公司目前是會通過訊息記錄到clickhouse,如果日誌量比較大,實時同步記錄肯定不行。有如下幾種解決方法:

a. 加記憶體快取,日誌先堆到記憶體中,然後開啟多執行緒(目前我們實現為單執行緒)非同步同步。

b. 加記憶體快取會帶來記憶體管理問題,1. 可能導致記憶體暴漲。 2. 可能導致頻繁GC。 3. 日誌丟失風險較大。 一種解決方案是設定記憶體快取上限,並使用壓縮等方法降低日誌大小,但是該方法不能徹底解決問題。還有一種方法類似kafka和rocketmq採用的,使用mmp給日誌記錄到檔案。由於mmap效能接近記憶體,所以效能問題可以解決,而且如果機器重啟,作業系統會保證mmap裡的資料重新整理到磁碟,最後由於mmap不是使用jvm的堆記憶體,所以不會有GC問題。

c. 壓縮儲存,採用壓縮演算法對日誌壓縮,降低日誌大小。

d. 合併日誌,這是在日誌同步時候要做的,合併日誌可以提高吞吐量。但是要注意合併日誌要注意分片的大小設定。

目前我們採用的是簡單的控制記憶體快取大小,因為目前我們的日誌量不大,後續在根據情況進行優化。