現象:
李景發佈laputa小需求,修改offer大圖邏輯,調用search,重啓不久出現cpu佔用一度飆升到45左右。
背景:
排查過程:
what:
cpu佔用過高,而且幾乎暫用了全部的8核,肯定是線程死循環導致的。
查看java線程,cpu佔用800-900%,查看java線程信息(top -H),發現部分線程cpu佔用時間極高,取9288 lwp(內存佔用在50%左右),查看堆棧信息,如下:
線程處於運行狀態,但是始終沒跳出HashMap.put方法,而303行是多線程觸發死循環的代碼點,初步定位hashmap死循環
查看幾個暫用cpu高的線程都這樣,並且線程始終不退出,基本定位hashmap的死循環問題。
注:中間時看cpu佔用,每個線程佔用沒有達到100%,以爲是不是死循環,一般死循環cpu佔用都100%,後來發現,進入死循環狀態的線程有多達69個,cpu不夠用了,所以纔出現佔用不到100%,排查疏忽
why:
查看代碼,發現代碼hashmap掛起在org.apache.velocity.util.introspection.ClassMap的內部實現,調用一個cache屬性,該屬性是new hashmap,我記得早前看過velocity代碼,這裏的實現不是這樣。
發現laputa,引用的velocity是1.6.1,看下代碼,如下:
而velocity 1.6.4時改成如下:
通過MapFactory.create夠造map,看了實現,默認構造concurrentHashMap
而我看的是1.7代碼,實現更優雅,直接concurrentHashMap。
再詢問應用負責人明東,之前沒有遇到過類似問題,而這次應用開發時就出現過兩次cpu佔用100%,肯定是需求引入。
對比線上之前的rpm包,發現老的應用引用的都是1.6.4,包依賴問題。
和李景過下,用maven打印依賴數,cms包依賴velocity1.6.1,引入時沒逐出,至此問題找到。
附件是jstack信息。
總結:
1.目前一個應用引用了太多技術干擾太多了,尤其對應用不是很熟悉,需要過濾各個框架問題
2.相信自己的經驗,確定大體思路再繼續排查,要不然沒方向
補充:
velocity bug report:
https://issues.apache.org/jira/browse/VELOCITY-718