這篇文章主要介紹“服務(wù)器故障實例分析”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強(qiáng),希望這篇“服務(wù)器故障實例分析”文章能幫助大家解決問題。
成都創(chuàng)新互聯(lián),是成都地區(qū)的互聯(lián)網(wǎng)解決方案提供商,用心服務(wù)為企業(yè)提供網(wǎng)站建設(shè)、成都app軟件開發(fā)、成都小程序開發(fā)、系統(tǒng)按需求定制制作和微信代運(yùn)營服務(wù)。經(jīng)過數(shù)10年的沉淀與積累,沉淀的是技術(shù)和服務(wù),讓客戶少走彎路,踏實做事,誠實做人,用情服務(wù),致力做一個負(fù)責(zé)任、受尊敬的企業(yè)。對客戶負(fù)責(zé),就是對自己負(fù)責(zé),對企業(yè)負(fù)責(zé)。
沒辦法,干it這一行,就得天天面對故障,大家就是傳說中的消防員,到處救火。不過,這次的故障范圍有點(diǎn)大,宿主機(jī)都打不開了。
好在監(jiān)控系統(tǒng)留下了一些證據(jù)。
證據(jù)發(fā)現(xiàn),機(jī)器的CPU、內(nèi)存、文件句柄,隨著業(yè)務(wù)的增長,持續(xù)的上升...上升....,直到監(jiān)控也無法將信息收集上來。
要命的是,這些宿主機(jī)上,部署了非常多的Java進(jìn)程。沒別的原因,就是為了節(jié)省成本,混部了應(yīng)用。當(dāng)宿主機(jī)表現(xiàn)出整體性的異常時,就難以找到罪魁禍?zhǔn)住?/p>
因為遠(yuǎn)程登錄也Over,暴躁的運(yùn)維只能重啟機(jī)器,重啟機(jī)器之后開始重啟應(yīng)用。經(jīng)過漫長的等待,所有的進(jìn)程都活了,但是,僅僅過了片刻,宿主機(jī)又立即死去。
業(yè)務(wù)一直處于死翹翹的狀態(tài),真是讓人惱火啊。也讓人心急。嘗試過幾次之后,運(yùn)維崩潰了,啟動了緊急預(yù)案:回滾!
最近的上線記錄有點(diǎn)多,而且有開發(fā)人員私自上線部署的行為,運(yùn)維蒙圈了:回滾哪些呢?還好有人腦瓜一亮,想起了還有find這個命令,那就找到最近更新的所有jar包,都給它來次回滾吧。
find /apps/deploy -mtime +3 | grep jar$
如果你不知道find這個命令,那可還真的是一場災(zāi)難。還好有人知道。
把十來個jar包回滾,還好沒有碰到數(shù)據(jù)庫的schema變更,系統(tǒng)終于正常運(yùn)行了。
沒別的辦法,查日志,進(jìn)行代碼審查。
代碼審查要追溯到最近1周或者2周之內(nèi)的代碼改動,因為有些功能代碼要沉淀一段時間,才能到線上風(fēng)光一把。
看著滿屏的提交記錄“OK”,技術(shù)經(jīng)理的臉都綠了。
“xjjdog說過,《80%的程序員,不會寫commit記錄》,我看你們是100%都不會寫”。
大家都靜悄悄的,忍著痛翻查歷史變更。經(jīng)過大家的不懈努力,終于在屎山之間,找到了一些問題代碼。CxO親自建了個群,大家一股腦的把可能會出問題的代碼,扔到了群里面。
"系統(tǒng)服務(wù)中斷了接近一個小時,影響非常惡劣",CxO說,“務(wù)必把問題徹底解決掉,這個問題投資人非常關(guān)注”!
okokok,有了釘釘?shù)闹?,大家的手勢都變得整齊劃一。
代碼有點(diǎn)多,大家對問題代碼討論了老久。包括一些使用并行流的,還有套在lamba表達(dá)式里的炫技代碼,還重點(diǎn)排查了一些線程池的使用代碼。
最后大家決定還是對線程池的代碼再過一遍。其中有一段是這么寫的。
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy(); ThreadPoolExecutor executor = new ThreadPoolExecutor(100,200, 60000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10), handler);
還別說,參數(shù)有模有樣的,甚至考慮到了拒絕策略。
Java的線程池,使得編程變的非常簡單。它有很多參數(shù),如上圖,我們一一介紹一下,否則代碼是無法審查的。
corePoolSize:核心線程數(shù),核心線程創(chuàng)建后會一直存活
maxPoolSize:最大線程數(shù)
keepAliveTime:線程空閑時間
workQueue:阻塞隊列
threadFactory:線程創(chuàng)建工廠
handler:拒絕策略
下面來介紹一下它們的關(guān)系。
當(dāng)線程數(shù)小于核心線程數(shù)的時候,有新的任務(wù)到來,將會生成一個新的線程進(jìn)行服務(wù)。當(dāng)當(dāng)前線程數(shù)大于核心線程數(shù),而且阻塞隊列未滿的時候,將會把任務(wù)放在阻塞隊列中。當(dāng)線程數(shù)大于核心線程數(shù),而且阻塞隊列滿了的時候,將會創(chuàng)建新的線程進(jìn)行服務(wù),直到線程數(shù)到達(dá)maximumPoolSize的大小。此時,如果還有新的任務(wù),將觸發(fā)拒絕策略。
再說一下拒絕策略。jdk默認(rèn)實現(xiàn)了4種策略,默認(rèn)實現(xiàn)的是AbortPolicy,也就是直接拋出異常。下面介紹其他幾種。
DiscardPolicy 比abort更加激進(jìn),直接丟掉任務(wù),連異常信息都沒有
CallerRunsPolicy 由調(diào)用的線程來處理這個任務(wù)。比如一個web應(yīng)用中,線程池資源占滿后,新進(jìn)的任務(wù)將會在tomcat線程中運(yùn)行。這種方式能夠延緩部分任務(wù)的執(zhí)行壓力,但在更多情況下,會直接阻塞主線程的運(yùn)行
DiscardOldestPolicy 丟棄隊列最前面的任務(wù),然后重新嘗試執(zhí)行任務(wù)
這段線程池的代碼是新加的,參數(shù)設(shè)置還算正常,并沒有什么大的問題。唯一有可能的風(fēng)險,就是使用DiscardOldestPolicy 的拒絕策略。當(dāng)任務(wù)非常多的時候,這個拒絕策略會造成任務(wù)排隊,請求超時。
當(dāng)然不能放過這種風(fēng)險,說實話也是到現(xiàn)在為之能夠找到的最可能的風(fēng)險代碼了。
"把DiscardOldestPolicy 改成默認(rèn)的AbortPolicy吧,重新打包上線一下試試“。技術(shù)大牛在群里說。
結(jié)果,服務(wù)灰度上線之后,宿主機(jī)不多時,就死掉了。是它的原因沒跑了,但是why?
線程池的大小 ,最小100,最大200,說什么也不過分。阻塞隊列的容量只有10,說什么也不會造成問題。你要說是這個線程池造成的原因,打死我都不信。
但是業(yè)務(wù)部門反饋,這段代碼加上就死,不加就沒事。技術(shù)大牛們抓耳撓腮百思不得其姐。
到最后,終于有人忍不住了,下載下業(yè)務(wù)的代碼打算調(diào)試一下。
當(dāng)他打開Idea的時候,瞬間懵逼了,又瞬間領(lǐng)悟了。他終于明白了這段代碼為什么會產(chǎn)生問題了。
線程池,竟然是在方法里創(chuàng)建的!
當(dāng)每一個請求到來的時候,它都會創(chuàng)建一個線程池,直到系統(tǒng)再也無法分配資源為止。
可真是霸道啊。
所有人都在關(guān)注線程池的參數(shù)是怎么設(shè)置的,但從來沒有人懷疑這段代碼所在的位置。
關(guān)于“服務(wù)器故障實例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點(diǎn)。
分享文章:服務(wù)器故障實例分析
文章位置:http://muchs.cn/article14/jcghde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、品牌網(wǎng)站建設(shè)、虛擬主機(jī)、微信公眾號、外貿(mào)建站、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)