"服務(wù)不可用"怎么排查?講了100遍還是記不住?
點(diǎn)擊上方藍(lán)色“小哈學(xué)Java”,選擇“設(shè)為星標(biāo)”
回復(fù)“資源”獲取獨(dú)家整理的學(xué)習(xí)資料!


下面是線上機(jī)器的cpu使用率,可以看到從4月8日開始,隨著時(shí)間cpu使用率在逐步增高,最終使用率達(dá)到100%導(dǎo)致線上服務(wù)不可用,后面重啟了機(jī)器后恢復(fù)。

1、排查思路
簡(jiǎn)單分析下可能出問題的地方,分為5個(gè)方向:
系統(tǒng)本身代碼問題 內(nèi)部下游系統(tǒng)的問題導(dǎo)致的雪崩效應(yīng) 上游系統(tǒng)調(diào)用量突增 http請(qǐng)求第三方的問題 機(jī)器本身的問題
2、開始排查
查看日志,沒有發(fā)現(xiàn)集中的錯(cuò)誤日志,初步排除代碼邏輯處理錯(cuò)誤。 首先聯(lián)系了內(nèi)部下游系統(tǒng)觀察了他們的監(jiān)控,發(fā)現(xiàn)一起正常。可以排除下游系統(tǒng)故障對(duì)我們的影響。 查看provider接口的調(diào)用量,對(duì)比7天沒有突增,排除業(yè)務(wù)方調(diào)用量的問題。 查看tcp監(jiān)控,TCP狀態(tài)正常,可以排除是http請(qǐng)求第三方超時(shí)帶來的問題。 查看機(jī)器監(jiān)控,6臺(tái)機(jī)器cpu都在上升,每個(gè)機(jī)器情況一樣。排除機(jī)器故障問題。即通過上述方法沒有直接定位到問題。
3、解決方案
1、重啟了6臺(tái)中問題比較嚴(yán)重的5臺(tái)機(jī)器,先恢復(fù)業(yè)務(wù)。保留一臺(tái)現(xiàn)場(chǎng),用來分析問題。
2、查看當(dāng)前的tomcat線程pid。

3、查看該pid下線程對(duì)應(yīng)的系統(tǒng)占用情況。top -Hp 384

4、發(fā)現(xiàn)pid?4430?4431?4432?4433?線程分別占用了約40%的cpu
5、將這幾個(gè)pid轉(zhuǎn)為16進(jìn)制,分別為114e?114f?1150?1151
6、下載當(dāng)前的java線程棧?sudo -u tomcat jstack -l 384>/1.txt
7、查詢5中對(duì)應(yīng)的線程情況,發(fā)現(xiàn)都是gc線程導(dǎo)致的

8、dump java堆數(shù)據(jù)
sudo -u tomcat jmap -dump:live,format=b,file=/dump201612271310.dat 384
9、使用MAT加載堆文件,可以看到j(luò)avax.crypto.JceSecurity對(duì)象占用了95%的內(nèi)存空間,初步定位到問題。
MAT下載地址:
http://www.eclipse.org/mat/

10、查看類的引用樹,看到BouncyCastleProvider對(duì)象持有過多。即我們代碼中對(duì)該對(duì)象的處理方式是錯(cuò)誤的,定位到問題。
4、代碼分析
我們代碼中有一塊是這樣寫的

這是加解密的功能,每次運(yùn)行加解密都會(huì)new一個(gè)BouncyCastleProvider對(duì)象,放倒Cipher.getInstance()方法中。
看下Cipher.getInstance()的實(shí)現(xiàn),這是jdk的底層代碼實(shí)現(xiàn),追蹤到JceSecurity類中

verifyingProviders每次put后都會(huì)remove,verificationResults只會(huì)put,不會(huì)remove.
看到verificationResults是一個(gè)static的map,即屬于JceSecurity類的。所以每次運(yùn)行到加解密都會(huì)向這個(gè)map put一個(gè)對(duì)象,而這個(gè)map屬于類的維度,所以不會(huì)被GC回收。這就導(dǎo)致了大量的new的對(duì)象不被回收。
5、代碼改進(jìn)
將有問題的對(duì)象置為static,每個(gè)類持有一個(gè),不會(huì)多次新建。

6、本文總結(jié)
遇到線上問題不要慌,首先確認(rèn)排查問題的思路:
查看日志 查看CPU情況 查看TCP情況 查看java線程,jstack 查看java堆,jmap 通過MAT分析堆文件,尋找無法被回收的對(duì)象
題外話: 目前小哈正在個(gè)人博客(新搭建的網(wǎng)站,域名就是犬小哈的拼音)?www.quanxiaoha.com?上更新《Go語言教程》,畢竟Go自帶天然的并發(fā)優(yōu)勢(shì),后端的同學(xué)還是要學(xué)一下的,這個(gè)教程系列小哈會(huì)一直更新下去,目前已經(jīng)更新到 Go語言的基礎(chǔ)語法了,歡迎小伙伴們?cè)L問哦~
END
有熱門推薦?
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。
謝謝支持喲 (*^__^*)


