客戶說:「今天的預報又沒有發出去,幫忙看下怎麼回事?」面試
「...」windows
登錄服務器,發現程序一直在打印服務器
running running running ...
這是代碼中寫的.net
public static void Main(string[] args) { Console.Title = string.Format("Grib2壓碼程序 請勿關閉"); ActiveMq(); while (hasMessage) { Console.WriteLine("running"); Thread.Sleep(1000); } }
程序經過啓動ActiveMQ,而後判斷是否仍有消息在處理,若是在處理就Sleep當前線程,等待處理完畢線程
當接收到消息時的處理主邏輯:日誌
public static void OnMessage(IMessage message) { var msg = message as ITextMessage; if(msg != null) { hasMessage = true; String date = msg.Text; Compress(date); mq.send(date); hasMessage = false; } }
那麼問題應該是Compress
或者 mq.send
一直在處理,卡住了??code
由於是.net程序,因此不能用jstack來分析線程了orm
經過windows自帶的任務管理器,把程序dump出來blog
而後使用windbg分析一下線程,直接經過文件, "open dump file",打開導出的dmp文件。string
windbg第一次使用,不是很懂得使用,可是注意到右下角threads的線程信息,發現只有一個主線程在運行!!
也就是說:咱們的監聽線程退出了!!!
那麼,什麼狀況下會退出呢?
通常是線程運行過程當中拋出異常沒有處理
檢查源代碼,發現程序沒有對出現異常作任何處理
因此,修改方案以下:
public static void OnMessage(IMessage message) { var msg = message as ITextMessage; if(msg != null) { hasMessage = true; String date = msg.Text; if(Compress(date, 3)) { mq.send(date); } else { mq.fail(date); } hasMessage = false; } } public static bool Compress(string date, int retry) { if (retry == 0) { return false; } try { Compress(date); return true; } catch (Exception ex) { Log.writeException(ex); return Compress(date, retry - 1); } }
將監聽消息部分的代碼進行修改,增長重試,並進行try catch異常處理,出現異常時,在文件中記錄日誌
固然mq.send
也有可能出現異常,將send方法也進行try catch異常處理
替換程序,上線運行(這種問題看可否重現了,重現了就能夠在error.log中找到了)
windbg第一應用,表示不少信息都看不懂
主線程中須要考慮子線程的異常,有些線程,你覺得在運行,實際上它退出了
面試的時候,面試官問我
「你遇到過最難解決的問題,你是怎麼解決的?」
「我特麼都是問題解決了就忘記了,因此沒啥印象」
不過,我是在內心說的
因此,對於別人問個人問題,我決定記錄下來,省得未來忘記了