背景
随着外賣業務的快速發展,業務複雜度不斷增加,線上系統環境有任何細小波動,對整個外賣業務都可能産生巨大的影響,甚至形成災難性的雪崩效應,造成巨大的經濟損失,因而每一次客訴、系統抖動等都是對我們技術人員的重大考驗:我們必須立即響應,快速解決問題。但是,如何提高排查問題的效率呢?最有效的方式是通過分析系統日志。如果系統日志全面,會給我們排查解決線上問題帶來絕大幫助,但是要想保證系統日志全面,就必須列印出所有的系統或業務日志,這樣就會帶來另一個問題:日志量的暴漲,過多的日志除了能夠幫助我們解決問題外,同時會直接造成系統性能下降,極端情況下,甚至導緻系統當機。在這種背景下,為了兼顧性能和快速響應線上問題,我們設計開發了日志級别動态調整元件。通過使用該元件,可以在需要解決線上問題時,實時調整線上日志輸出級别,擷取全面的debug日志,幫助工程師提高定位問題的效率。
場景介紹
場景一:
業務依賴複雜,某一時刻,依賴的下遊服務故障,導緻請求大量逾時,尤其是對于外賣這種集中性特别明顯的業務,平均每秒QPS在8000以上,1分鐘的故障就會集中産生大量的錯誤日志,導緻磁盤IO急劇提高,耗費大量cpu,進而導緻整個服務癱瘓。如果該業務不能立即降級,怎麼辦?
修改日志級别,發版上線,流程長,操作麻煩暫且不談,同時存在引入其它故障的高風險。如果系統恰好使用的log4j版本,在面對極短時間内列印出的海量錯誤日志,會快速耗盡buffer區記憶體,進而拖慢主線程,造成服務性能整體下降,甚至還未來得及修複問題,海量日志已經拖垮服務,造成服務當機了,損失慘重。
場景二:
大量的訂單、結算等客訴問題回報過來,一線工程師大量精力埋沒于排查問題中,而排查定位問題的最終手段仍然是依賴線上日志,由于鍊路較長,任一日志的缺失,都給問題的排查帶來極大的障礙,面對營運的催促,怎麼辦?
工程師為了以後排查問題的友善,在任一可能出現異常的地方,列印出關鍵日志。然後發版上線,好不容易解決了本次問題,還沒來得及收獲喜悅,就又面臨着一個新問題,請看場景三。
場景三:
由于線上業務系統預設日志列印級别是INFO級别,為了排查問題友善,調試型日志都以該級别列印出,給系統帶來了額外的負擔,高峰期大量調試日志拖慢系統性能,增大出故障的風險,怎麼辦?
一方面要快速響應業務,另一方面要兼顧系統性能,是否可以兩方面都兼顧?我們的動态調整日志級别工具正是為了解決這種痛點。
該元件能夠解決什麼問題?
1、日志降級。相容log4j、log4j2和logback主流日志架構,如果遇到場景一,可以通過我們的日志工具,快速調整日志輸出級别,降低系統日志的輸出,進而達到日志降級的效果,同時能夠給RD争取充裕的排查問題時間。
2、規範日志級别濫用,幫助工程師快速定位解決線上問題。使用日志級别動态調整元件,可以實時動态調整線上服務的日志列印級别,調試型日志可以使用低級别列印出,減輕線上服務的負載壓力,遇到排查問題時,可以臨時将日志級别調低,快速得到精準化的日志資訊,排查解決問題。
系統基礎架構
日志級别動态調整元件定位為中間件,在設計之初重點考慮了以下幾點:
1、低侵入性
- 接入服務僅需要引入jar包和xml配置檔案即可,不存在額外編碼工作,業務耦合低,接入成本小。
2、安全可靠
- 更改接入服務的日志輸出級别,隻能通過我們授權的背景系統操作,所有的操作記錄有迹可查。
- 引入權限認證,確定工程師隻能操作自己負責的服務或系統,同時會把操作内容實時周知給系統的所有相關責任人,避免誤傷。
3、可視化操作
- 操作者可以通過我們提供的管理頁面,定向修改一個或一批服務節點。
- 提供可視化的操控開關,可以随時關閉或開啟服務。
具體實作
核心調用元件
本元件采用工廠模式實作,保障其高可擴充性。目前已實作日志級别動态調整和方法調用處理單元,下面主要介紹日志級别動态調整處理單元的實作。
目前咱們外賣業務系統基本統一采用的slf4j日志架構,在應用初始化時,slf4j會綁定具體的日志架構,如log4j、logback或log4j2等。具體源碼如下(slf4j-api-1.7.7):
|
findPossibleStaticLoggerBinderPathSet方法用來查找目前classpath下所有的org.slf4j.impl.StaticLoggerBinder類。每一個slf4j橋接包中都有一個StaticLoggerBinder類,該類實作了LoggerFactoryBinder接口。具體綁定到哪一個日志架構則取決于類加載順序。
接下來,咱們分三部分,來說說ChangeLogLevelProcessUnit類:
1.初始化:确定所使用的日志架構, 擷取配置檔案中所有的logger記憶體執行個體,并将它們的引用緩存到map容器中。
|
2.擷取logger清單:從本地map容器取出。
|
3.修改logger的級别
|
上面介紹了log架構在啟動加載時,如何拿到系統日志配置檔案中的logger,以及具體修改logger級别的實作方法。
通信方式
我們根據web項目和純粹RPC項目,分别提供http和thrift兩種通信協定。
一、thrift服務
|
所有的請求資訊都包含在jsonString的資料結構裡面,其中包含有簽名資訊,請求時簽名驗證失敗将直接抛出異常。
引入元件提供的dynamic-invoker.xml配置,将會在系統中自動注入開啟一個專為日志級别調整的接口服務,該接口是一個單純的thrift服務,能夠通過zookeeper實作服務注冊與發現,并且有可視化的開啟與關閉管理背景,簡單明了,操作友善。
二、http服務
對于一些web項目,暴露一個rpc服務相當不安全。為此,我們提供了http協定接口,接入流程完全一樣,在真正修改日志輸出級别時,會根據系統類型自主判斷使用哪種協定,有獨立實作的簽名認證,安全可靠。
招聘
歡迎感興趣的同學随時與我們溝通交流,我們有高并發的業務,有各種牛逼的中間件技術,期待您的加入,我們一起成長。
履歷砸來:[email protected];
微信二維碼: