這個是我很早以前解決的乙個案例,其現象是系統每次上線後,20多台機器,總有兩三機器,出現假死的情況。如何判斷出系統假死?借助的是乙個第三方公司運維監控平台;這種情況,前同事稱之為的「假死」,需要重新啟動系統才能恢復。因為我是新來乍到,覺得這種情況不正常,而且對研發(在這邊是研發上線)來說,是乙個非常大的上線負擔;於是我決定解決一下這個「百年難題」。
我親自上線,果然很快就碰到了假死的機器。我看到機器的cpu,記憶體和磁碟io都很正常,根本不像出問題的機器。直覺告訴我,先用jstack列印個堆疊看看當前tomcat在做什麼吧,於是叫上支援上線的運維小哥給列印了乙個,然後手工重新部署了一下有問題的機器(記住出問題一定要先止損)。
拿到手的堆疊,第一眼就發現了一些問題。前幾行如下:
可以看到tomcat的執行緒號已經到了215,而tomcat預設最大處理數為200,已經到了飽和狀態。後續的請求就只能排隊了。
堆疊中,有很多waiting to lock <0x0000000784588098>的執行緒,從執行堆疊看,應該是cxf要呼叫.net的webservice。呼叫的業務方法各不相同。
繼續往下看,在堆疊的後半部分(注意行數),列印了乙個死鎖的提示。
我們進一步分析,可以看出,執行緒25和執行緒48形成了死鎖。這4個執行緒的等待關係如下:
繼續分析,什麼導致的死鎖;
執行緒25的堆疊如下:
執行緒48的堆疊:
執行緒持有鎖和堆疊中提示的鎖資訊正好照應
從上面堆疊可以分析出,gson和第三方的agent發生了迴圈死鎖。至此問題的解決方法已經有了,要不去掉gson,要不就去掉那個第三方agent。
除了上面的解決方法外,我們還在系統中增加了乙個容器探活的介面(這個功能從監控來看,非常有意義)。即在controller中寫乙個方法,直接返回乙個字串。這樣在外部定時的去呼叫介面(也可以手工使用curl來探測),就知道這個服務是否還存活,也不用第三方監控系統來判斷了;
經驗教訓:
1、系統需從容器級別支援外部探測,以證明自身健康
2、不要輕易引入外部agent
知識點:
1、tomcat(bio)預設最大執行緒數200
記一次網路故障排查
背景 a到b網路通暢,偶爾出現a連線b的80服務出現連線超時。b埠開通。兩端防火牆與埠無關,排除伺服器防火牆干擾。排查思路和方法 0.首先確認是否網路丟包,或者兩端伺服器網絡卡跑滿,伺服器負載較高。1.mtr 需要mtr 0.85版本及以上版本。mtr first ttl 5 tcp port 80...
記一次LINUX CRONTAB失敗的排查案例
在crontab 設定計畫任務,每天凌晨3點執行指令碼 conrtab 3點 tomcat使用者 執行指令碼 推送備檔案 目標伺服器 同時將過程寫入log記錄 然而在第二天例常檢查後,發現計畫任務沒有達到預期效果 var log cron如下 jan 30 03 00 01 z00w00 host ...
記一次ActiveMQ的異常排查
做乙個小專案時,選擇使用 activemq 作為中介軟體,負責專案內各元件的通訊。剛部署時,整個專案執行正常。執行 n 天後,發現 activemq 出乎意料地自動重啟,進而導致佇列中未來得及消費的資料丟失。剛開始,以為是配置檔案 activemq.xml 的問題,但是仔細核查後,發現沒有什麼明顯的...