因打印日志而引發的故障


問題描述:

最近已經有兩個項目因為日志打印問題而引發了故障,可以說是血的教訓了。兩次故障的原因也是非常的相似,都是由於其他業務系統調用了另外一個老系統的接口,但是由於傳遞的參數不正確,而老系統會因為參數不正確而打印日志。當錯誤的請求量增大,打印日志會造成當前線程阻塞,容易使機器機器負載升高,產生性能問題

排查方法:

1. 直接查看機器上日志大小

2. 還可以通過Jstack查看 占用cpu最多的線程,多查看幾次,如果每次都是打印日志的線程,那基本上也可以確定是打印日志的問題

解決方案:

1. 提前校驗參數,如果參數有問題應該拋出異常

2. 在logback的AsyncAppender中配置<neverBlock>true</neverBlock> 避免業務線程的阻塞

<!-- 異步輸出 -->
    <appender name ="STDOUT_ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold >0</discardingThreshold>
        <queueSize>512</queueSize>
        <includeCallerData>false</includeCallerData>
        <neverBlock>true</neverBlock>
        <appender-ref ref ="stdout"/>
    </appender>

Logback的neverBlock原理:

由於logback相當於是生產者-消費者模式,當時我們在系統中ogger.info()或者ogger.error()時,是把日志信息加入到logback的隊列中,默認是調用隊列的put方法,而當隊列滿了之后,就會阻塞當前的線程。而設置了neverBlock后,則會調用offer方法,如果隊列滿了,則丟棄。可以查看源碼:

 


免責聲明!

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



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