來源:捕風 發(fā)布時間:2018-12-08 14:56:57 閱讀量:1377
分析這個問題的過程還是挺曲折,如果不想看繁瑣的分析過程,請直接跳到結(jié)論
我們小組的成員請耐心看一下過程,積累一下經(jīng)驗,到用戶現(xiàn)場是能學(xué)習(xí)很多東西的,以后你們要爭取到用戶現(xiàn)場,呵呵
---------------------------------------------------------------------------------------------------------------------------------------------------------
周一下午到移動時發(fā)現(xiàn)服務(wù)器的情況是這樣的
1.ESServer內(nèi)存達到差不多200M,且以緩慢的速度不斷上升,ESServer進程一直占用CPU約6%-10%
2.服務(wù)器生成了一堆大小為0KB的DUMP
3.有大量因沒有管理網(wǎng)段的客戶端不斷地每隔一分鐘取策略
4.日志只有很少
---------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------
在現(xiàn)場解決了兩個問題
1.配置管理網(wǎng)段,讓客戶端不再取策略,并且重啟ESServer,CPU占用率降了不少,平均1%-2%(且不是一直占用),內(nèi)存沒有發(fā)現(xiàn)上升(不排除是以更慢的速度上升,要等后面觀察)
2.日志太少的原因是因為INI配置的日志文件只有10M,且只有一個備份,后將參數(shù)改為了1G(有一個奇怪的現(xiàn)象是,服務(wù)器的日志已經(jīng)成功寫入文件,但文件的修改時間一直不變)
---------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------
在重啟ESServer服務(wù)器時,很“有幸”地遇到一個崩毀,生成了55M的dump,趕緊拿回來分析
1.經(jīng)過一番分析,發(fā)現(xiàn)崩毀是某個鎖在已經(jīng)被刪除的情況下還繼續(xù)使用導(dǎo)致
2.分析了代碼,這個鎖在服務(wù)器停止前都不會被刪除的,而這次崩毀剛好又是在我停止服務(wù)器時發(fā)生的
3.寫個模擬這種情況的測試程序,肯定也能這樣崩毀,但畢竟這個程序不是服務(wù)器,只能作出推斷,是多線程造成的問題,當停止服務(wù)器時,對象已經(jīng)銷毀,但還有線程剛好在用這個鎖,這是一個很偶然的情況(T_T)
到這里,發(fā)現(xiàn)這個崩毀竟和之前的周期性崩毀沒多大關(guān)系……(我崩毀了……),因為:
1.上面的崩毀是在一個很偶然的情況下發(fā)生的,很難周期性發(fā)生
2.上面的崩毀生成了55M的dump,周期性崩毀只生成了0KB的dump
---------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------
問題還是沒有找到,但既然懷疑這部分代碼有多線程問題,就從這里出發(fā)查找:
1.發(fā)現(xiàn)代碼里面這部分用得最多的就是日志模塊,聯(lián)系到那天國富跟我說他將日志參數(shù)從info改為debug時可能可以加快問題的發(fā)生,我就在服務(wù)器專門開兩條線程不斷地寫日志,發(fā)現(xiàn)下面了問題
2.大量的日志寫入,導(dǎo)致待寫入日志的隊列內(nèi)存不斷升高(因為寫入文件的速度和寫入內(nèi)存的速度不是一個等級導(dǎo)致的),導(dǎo)致最后因空間不夠,list在pushback的時候發(fā)生崩毀(為何stl會實現(xiàn)成這樣還得深究)
3.以服務(wù)啟動時,在崩毀的時候竟然生成了一個0KB的dump,“大喜”,因為這和移動的現(xiàn)象很類似(內(nèi)存高,0KB的dump)
---------------------------------------------------------------------------------------------------------------------------------------------------------
其實以前天珣的代碼編寫者估計也想到這個問題,他限制了隊列的最大長度是1024,但為什么還會出現(xiàn)這個問題呢,原來又是多線程和判斷不嚴謹?shù)膯栴},且看下面分析
1.在進入隊列前,會先鎖定然后判斷隊列是否已經(jīng)滿了,但這個鎖在IsFull()后就解鎖了,就存在如果同時有多線程PUT的時候,大家都做完IsFull()這個函數(shù)后再做doPut(),而判斷隊列是否滿又竟然只用了“==”,就造成了隊列大于1024,隊列還會繼續(xù)增加的情況。
2.最簡單的修改方法就是將“==”改為“<=”,雖然沒有改變多線程問題的本質(zhì),但足以很好地修復(fù)這問題
---------------------------------------------------------------------------------------------------------------------------------------------------------
結(jié)論:
1.這個問題估計是一直都存著的,只是需要條件觸犯。在移動,大量客戶端重復(fù)取策略,日志文件增長得很快(開了DEBUG更快),內(nèi)存CPU很高,且和我這里重現(xiàn)的現(xiàn)象很類似,所以現(xiàn)階段只能推斷是這個原因造成的。但不明白的是,建行也出現(xiàn)過大量客戶端重復(fù)取策略,卻沒有這種崩毀。
2.現(xiàn)在配了管理網(wǎng)段,客戶端不再重復(fù)取策略,日志改為info,增加比較慢,問題應(yīng)該會有所緩和,國富可先不跟移動說,再觀察那邊服務(wù)器情況一段時間。要修復(fù)的話只需按上面說的修復(fù)即可。
看來多線程的確是一個博大精深的問題,我由此擔憂6694客戶端這么多線程會不會埋著什么雷呢?
一切只是推斷,需要時間驗證,以上權(quán)當學(xué)習(xí)總結(jié)
---------------------
在線
客服
客服
熱線
7*24小時客服服務(wù)熱線
關(guān)注
微信
關(guān)注官方微信