老闆:再用Log4j就收拾東西回家吧!

以前一段時間,爲咱們發現的一個SaaS應用程序會間歇性地卡頓、變慢,由於很長時間都沒有定位到緣由,因此解決的辦法就只能是重啓。數據庫

這個現象和以前咱們遇到的程序變得卡頓不太同樣,由於咱們發現這個應用程序不只在高流量期間時會變慢,有時在低流量時期也會變慢。因此這令你們都很奇怪。apache

這類應用程序的變慢,從新啓動以後就能夠維持一段時間,可是過段時間又有可能會再次出現。編程


故障排除
當咱們準備排查這個問題的時候,咱們在應用程序速度很慢的時候,嘗試着捕獲了這個應用程序的線程Dump。有不少種方式來捕獲線程轉Dump,咱們選擇了「jstack」工具來獲取。
在問題發生時得到線程Dump是很是關鍵的!
而後咱們將捕獲的線程Dump上傳到一個線上線程Dump分析工具(https://fastthread.io/)。該工具當即幫咱們生成了一份報告。
報告當即找出了問題的根本緣由。分析工具上顯示「http-nio-8080-exec-121」線程阻塞了100多個線程。下面是傳遞依賴圖,展現了阻塞線程:
從圖中能夠看到100多個線程被「http-nio-8080-exec-121」線程阻塞。當咱們點擊圖中的「http-nio-8080-exec-121」超連接時,它會打印出線程的堆棧軌跡:
仔細觀察圖中被框出來的部分,你能夠看到該線程已經獲取到 org.apache.log4j.Logger 的鎖,正在進行其餘的操做。
接下來,咱們隨便找一個被"http-nio-8080-exec-121"阻塞的線程,看一下他的堆棧信息:
看一下上面堆棧跟蹤中被框出來的部分。咱們能夠看到「http-nio-8080-exec-56」當前正處於阻塞(BLOCKED)狀態,而阻塞的緣由是它正在等待獲取 org.apache.log4j.Logger 的鎖。
前面咱們剛剛分析過,「http-nio-8080-exec-121」得到了org.apache.log4j.Logger的鎖,正在進行其餘操做,而鎖並無被釋放,因此其餘線程想要得到鎖就只能被阻塞。
其他的全部被阻塞的線程也在等待獲取 org.apache.log4j.Logger 的鎖。所以,每當任何應用程序線程試圖記錄日誌時,它都會由於沒法獲取到鎖而進入阻塞狀態。
剛開始咱們也沒有太多的頭緒,後來咱們嘗試藉助Google的力量,而後咱們用谷歌搜索了"org.apache.log4j.Logger 阻塞 線程"這樣的關鍵字。
咱們在Apache Log4j bug數據庫中偶然發現了這個有趣的Bug,並且這個Bug早在2015年就被發現了。(https://bz.apache.org/bugzilla/show_bug.cgi?id=57714 )。
這是Log4J框架中已知的bug之一,也是開發新的Log4j2框架的主要緣由之一。
因爲這個bug,任何試圖打印日誌的線程都進入了阻塞狀態。它致使整個應用程序嘎然而止。一旦應用程序從Log4j遷移到Log4j2框架,問題就解決了。

結論
Log4j已經在2015年8月開始就再也不被維護了。若是您的應用程序仍在使用Log4J框架,強烈建議升級到Log4j2框架。Log4j2不只僅是Log4j框架的下一個版本,它是一個從零開始編寫的新框架,它有不少性能改進。
最後,若是網站遇到程序被拖慢的問題,那麼也能夠考慮一下這個因素。
關於做者漫話編程,是一個經過漫畫+音頻的形式講解枯燥的編程知識的公衆號。致力於讓編程變得更有樂趣。



        

往期推薦c#

京東熱 key 探測框架新版發佈,單機 QPS 可達 35 萬微信


Docker真的被禁止使用了?併發


《Java開發手冊》解讀:大整數傳輸爲什麼禁用Long類型?app


本文由「壹伴編輯器」提供技術支
 

直面Java第329期:哪一個命令能夠監控虛擬機各類運行狀態信息?框架

深刻併發第013期:拓展synchronized——鎖優化編輯器


若是你喜歡本文,
工具

請長按二維碼,關注 Hollis.

轉發至朋友圈,是對我最大的支持。


點個 在看 
喜歡是一種感受
在看是一種支持
↘↘↘

本文分享自微信公衆號 - Hollis(hollischuang)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索