解決java web應用線上系統偶發宕機的情況
前言:
事情是醬紫的,系統上線兩個月后,風平浪靜。在一個秋天寧靜的下午,老衲正喝著茶聽著歌敲著代碼,順便欣賞下妹紙,獨享這難得的愜意。突然手機響了,一看來電,心中一沉,項目經理來電,必有蹊蹺。匆忙接起電話,沒有問候,直奔主題,“趕緊看下系統,個別客戶反饋系統不能用了,先恢復系統,再排查問題”。
老衲撂下電話,一哆嗦,趕緊連上VPN,直奔服務器主機。
PS:三臺服務器(centos、128G內存、32核CPU),tomcat1.7,jdk1.8,通過F5負載
解決步驟:
1、top命令查看CPU占用情況
可以看到11042進程占用了非常多的CPU資源
2、查看F5并發曲線:為什么應用耗費了這么多的線程,難道是用戶量突然上來了,調取了F5的訪問曲線圖,可以看到在15:57左右并發量突然猛漲,當時根據曲線懷疑是請求量徒增導致
3、查看系統請求量:根據應用系統日志、以及localhost_access_log日志 查看此節點用戶訪問日志,發現使用人數并未徒增,根據請求量繪制的曲線如下:
可以看到曲線并未出現請求量徒增。
4、查看進程內線程運行情況:沒有大量請求,為什么CPU會被使用這么多,難道是有線程的死鎖,
執行top -p 11042 -H 查看進程內所有線程的運行情況:
可以看到有很多線程正在執行
5、接著打內存快照執行命令打內存快照 在 jdk1.8.0_131/bin下面執行 ./jstack -l 11042>log01.txt,然后又隔了一分鐘再次執行./jstack -l 11042>log02.txt,生產兩個文件好對比里面的線程交集
打開日志,并未發現死鎖的線程,但是在兩個文件里面卻發現大量的GC線程在執行如圖:
6、分析GC回收情況,在jdk bin目錄下執行 ./jstat -gcutil 11042 1000 100
看到了沒有,虛擬機正在瘋狂的進行full GC 回收,垃圾回收線程占用了非常多的CPU資源,問題已經有了明確的方向了,接下來需要分析到底是什么導致了full GC的頻繁觸發。
7、分析堆內存:
打印堆內存 在jdk bin目錄下執行 ./jmap -dump:live,format=b,file=problem.bin 11042 ,將日志文件下載到本地使用jprofiler分析,
發現有大量char[],String ,map 占用,那么是什么業務代碼造成了以上大量的數據呢,打開 char[],String 沒有找到與之關聯的業務代碼, 在map中發現大量的相同的業務對象,但是卻無法直接發現出是什么操作造成了大量業務對象的存在,因為此業務對象代碼中大量使用一一排除的話工作量極大。
一時陷入困境,靈機一動,是不是還有別的內存快照分析工具,一查有個mat,在eclipse裝好插件,打開內存快照:
點擊leak suspects,如圖
在個給出問題中一一查看,這時問題出現了如圖:
BaseDatagridRest 的export導出數據方法,突然想到系統中有某個表數據的導出,立即登錄系統查看此項導出功能,發現這個導出未對數據量做限制,而且BaseDatagridRest 的export方法實現是將數據庫中的表數據抽取到內存中然后回寫到excle中,讓用戶下載。
我登錄測試環境,用大數據量測試了下導出果然出現了同樣的問題,至此問題水落石出,解決方案很簡單,導出數據量加上限制,為了防止因為導出過慢時用戶多次點擊加上和遮罩。
總結:GC不只是用來面試的,更是來解決問題的。
以上這篇解決java web應用線上系統偶發宕機的情況就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。
相關文章:
1. 將properties文件的配置設置為整個Web應用的全局變量實現方法2. python中pandas.read_csv()函數的深入講解3. python爬蟲利用代理池更換IP的方法步驟4. JS算法題解旋轉數組方法示例5. SpringBoot集成SSM、Dubbo、Redis、JSP的案例小結及思路講解6. Python語言規范之Pylint的詳細用法7. springboot用controller跳轉html頁面的實現8. VMware如何進入BIOS方法9. JavaScript forEach中return失效問題解決方案10. PHP設計模式之迭代器模式Iterator實例分析【對象行為型】
