Logger性能優化


  最近排查線上問題,無意中發現了Logger堵塞的情況,排查的同時也做下總結,做個筆記,以防備用。

  先上圖,看下實際堵塞的情況

 

從圖中可以清楚的看到標黃的都在 waiting to lock <0x000000054011c380> 這個鎖,這個鎖被標紅線程持有,如果標紅的線程處理業務邏輯不夠快,哪其它線程就會一直處在 BLOCKED 中。

關於org.apache.logging.log4j.core.appender.OutputStreamManager的說明,可以查看官方文檔 點擊查看,關於Write重載的幾個方法如下

 

都有排它鎖,這樣在一個線程持有的時候,如果因為業務邏輯復雜、或者網絡延遲 等等 都有機會造成線上發生的堵塞情況。

         下面說下自己整理的主要優化方案

  1. 升級版本

    a)         Logback

    Logback與Log4j的對比可以看官方文檔 點擊查看,如果升級到Logback記得要開啟異步功能,進一步提高性能,異步配置如下

<appender name ="async" class= "ch.qos.logback.classic.AsyncAppender">
    <discardingThreshold >0</discardingThreshold>
    <queueSize>512</queueSize>
    <appender-ref ref ="file"/>
</appender>

  l  discardingThreshold     

默認情況下,當BlockingQueue還有20%容量,他將丟棄TRACE、DEBUG和INFO級別的event,只保留WARN和ERROR級別的event。為了保持所有的events,設置該值為0。

  l  queueSize

BlockingQueue的最大容量,默認情況下,大小為256。

  l  appender-ref

關聯的appender

    b)         Log4f2

是log4j的升級版,詳細資料可以查看官方文檔,點擊查看,我比較喜歡功能就是支持lambda,延遲加載就是利用這個功能實現的

  2. 延遲加載

延遲加載說直白點就是按需加載,只有在用到的時候觸發。你是否在項目中經常這樣寫日志

logger.info("消息提示:"+e.getMessage()+",業務數據:"+e.getData()+",級別別:"+e.getLevel().getName());

或者這樣

logger.info("消息提示:{},業務數據:{},級別別:{}", e.getMessage(), e.getData(), e.getLevel().getName());    

不管你用上面兩個示例中的哪種寫法,運行的時候,不管設置的級別是多少,都會執行e的方法,如果有序列化的情況會更糟糕。理想情況是根據設置的日志級別,只在真正調用的時候再執行,這時可以用如下寫法,做到按需索取日志

 logger.info("消息提示:{},業務數據:{},級別別:{}", () -> e.getMessage(), () -> e.getData(), () -> e.getLevel().getName());
  3. 根據環境設置不同的級別
根據程序運行的環境設置不同的日志級別,一般分為開發、測試、預上線、生產 環境,日志級別應該逐步提高,避免日志的IO頻繁讀寫提高性能,建議設置為debug、info、warn、warn


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM