在網際網路設計架構過程中,日誌非同步落庫,儼然已經是高併發環節中不可缺少的一環。為什麼說是高併發環節中不可缺少的呢? 原因在於,如果直接用mq進行日誌落庫的時候,低併發下,生產端生產資料,然後由消費端非同步落庫,是沒有什麼問題的,而且效能也都是異常的好,估計tp99應該都在1ms以內。但是一旦併發增長起來,慢慢的你就發現生產端的tp99一直在增長,從1ms,變為2ms,4ms,直至send timeout。尤其在大促的時候,我司的系統就經歷過這個情況,當時mq的傳送耗時超過200ms,甚至一度有不少timeout產生。
考慮到這種情況在高併發的情況下才出現,所以今天我們就來探索更加可靠的方法來進行非同步日誌落庫,保證所使用的方式不會因為過高的併發而出現介面ops持續下降甚至到不可用的情況。
此種方案由於使用了非同步方式,且由於非同步的discard policy策略,當大量資料過來,緩衝區滿了之後,會拋棄部分資料。此種方案適用於能夠容忍資料丟失的業務場景,不適用於對資料完整有嚴格要求的業務場景。
來看看具體的實現方式:
然後在log4j.xml中,為此類進行配置:
最後就可以按照如下的方式進行正常使用了:
注意: 此處需要注意log4j的乙個效能問題。在log4j的conversionpattern中,匹配符最好不要出現 c% l%萬用字元,壓測實踐表明,這兩個萬用字元會導致log4j打日誌的效率降低10倍。
方案一很簡便,且剝離了介面直接依賴mq導致的效能問題。但是無法解決資料丟失的問題(但是我們其實可以在本地搞個策略落盤來不及處理的資料,可以大大的減少資料丟失的機率)。但是很多的業務場景,是需要資料不丟失的,所以這就衍生出我們的另一套方案來。
此種方式,是開啟worker在後台增量消費log4j的日誌資訊,和介面完全脫離。此種方式相比方案一,可以保證資料的不丟失,且可以做到完全不影響介面的ops。但是此種方式,由於是後台worker在後台啟動進行掃瞄,會導致落庫的資料慢一些,比如一分鐘之後才落庫完畢。所以適用於對落庫資料實時性不高的場景。
具體的實現步驟如下:
首先,將需要進行增量消費的日誌統一打到乙個資料夾,以天為單位,每天生成乙個帶時間戳日誌檔案。由於log4j不支援直接帶時間戳的日誌檔案生成,所以這裡需要引入log4j.extras元件,然後配置log4j.xml如下:
之後在**中的申明方式如下:
最後在需要記錄日誌的地方使用方式如下:
這樣就可以將日誌列印到乙個單獨的檔案中,且按照日期,每天生成乙個。
然後,當日誌檔案生成完畢後,我們就可以開啟我們的worker進行增量消費了,這裡的增量消費方式,我們選擇randomaccessfile這個類來進行,由於其獨特的位點讀取方式,可以使得我們非常方便的根據位點的位置來消費增量檔案,從而避免了逐行讀取這種低效率的實現方式。
注意,為每個日誌檔案都單獨建立了乙個位點檔案,裡面儲存了對應的檔案的位點讀取資訊。當worker掃瞄開始的時候,會首先讀取位點檔案裡面的位點資訊,然後找到相應的日誌檔案,從位點資訊位置開始進行消費。這就是整個增量消費worker的核心。具體**實現如下(**太長,做了摺疊):
此種方式由於worker掃瞄是每隔一段時間啟動一次進行消費,所以導致資料從產生到入庫,可能經歷時間超過一分鐘以上,但是在一些對資料延遲要求比較高的業務場景,比如庫存扣減,是不能容忍的,所以這裡我們就引申出第三種做法,基於記憶體檔案佇列的非同步日誌消費。方案三:基於記憶體檔案佇列的非同步日誌消費
由於方案一和方案二都嚴重依賴log4j,且方案本身都存在著要麼丟資料,要麼入庫時間長的缺點,所以都並不是那麼盡如人意。但是本方案的做法,既解決了資料丟失的問題,又解決了資料入庫時間被拉長的尷尬,所以是終極解決之道。而且在大**過程中,此種方式經歷了實戰檢驗,可以大面積的推廣使用。
在實際使用的時候,arrayblockingqueue作為核心佇列,顯然是全域性加鎖的,後續我們考慮公升級為無鎖佇列,所以將會參考netty中的有界無鎖佇列:mpscarrayqueue。預計效能將會再好一些。
上面就是在進行非同步日誌消費的時候,我所經歷的三個階段,並且一步一步的優化到目前的方式。雖然過程曲折,但是結果令人歡欣鼓舞。如果喜歡就給個推薦,後續我將會持續更新你所不知道的系列,以期達到拋磚引玉的效果。
你以為這次只有好課?那是你沒了解我們的誠意
霍格沃茲測試學院感恩活動 時間已過,優惠還在 為了答謝學員們對霍格沃茲測試學院一如即往的支援,也歡迎新學員的加入!在此mtsc2019網際網路測試開發大會即將開幕之際。學院對內部學員開放乙個特殊的感恩回饋活動。mtsc2019門票領取方式 所有學員可通過如下活動之一獲得 機會 對於熱心宣傳霍格沃茲測...
你真的了解過挖礦嗎? 你又了解多少(一)
前面我說獲取位元幣的主要方法 購買和挖礦兩種。對於數字貨幣的購買,相比我就不用多說了吧 就是在乙個交易平台,購買你所需要的幣種。大部分人都是通過買幣的方式獲取幣種。可以你知道挖礦是低成本獲得幣種嗎?我來詳細說說挖礦的方法吧。挖礦是什麼 挖礦對於剛接觸數字貨幣小白甚至接觸過數字貨幣,都對於挖礦的認知不...
Vue外掛程式你有了解過嗎?
vue的外掛程式式很強大的,外掛程式的功能會使用vue全域性物件或者例項來呼叫,或者修改從而在vue的鉤子函式內起作用。vue.install vue的外掛程式必須提供乙個公開方法install,這個方法在你使用外掛程式,也就是vue.use 外掛程式 時被呼叫,相當於乙個外掛程式的註冊或者宣告。v...