使用Tomcat作為Web服務器的時候偶爾會遇到Tomcat停止響應的情況,通過netstat查看端口情況會發現tomcat的端口出現大量的CLOSE_WAIT,此時Tomcat會停止響應前端請求,同時服務端的日志,操作等將全部停止,而且沒有出現任何異常,此時就需要排查是哪方面的原因,此案以以前的解決為例總結排查方案
1、首先確認頁面端正常時請求沒有問題
2、對於使用Nginx作為前端負載均衡Tomcat集群,通過Nginx的訪問日志(access.log)確認頁面到Nginx沒有問題
3、查看Tomcat的訪問日志(localhost_access_log.txt)查看前端請求是否訪問到Tomcat
4、查看Tomcat的狀態控制台,查看Tomcat的請求和內存占用情況
查看那些請求處於等待狀態,排查這些請求的服務是否存在問題(長事務、頻繁事務)
5、查看數據庫進程查看當前數據庫實例是否出現死鎖
如果出現死鎖,排查代碼中出現死鎖的原因,解決死鎖問題
6、如果以上都沒有問題,排查代碼中的定時任務
查看定時任務事務是否存在問題(長事務、頻繁事務)
7、檢查是否是頻繁的寫日志造成Tomcat阻塞
對於訪問量比較大的系統,如果項目采用Info或者Debug日志級別的話會造成Tomcat頻繁的讀寫幾百兆甚至上G的日志文件,造成Tomcat阻塞
曾經遇到的一次Tomcat出現CLOSE_WAIT時,通過排查發現是一位同事在通過定時任務做其他系統的數據同步時時出現的問題造成的,問題總結如下:
1、同步其他系統的數據是耗時較長,其采用Spring的切面事務,造成同步時事務時間長達幾分鍾時間,存在死鎖風險
2、同步數據完需要處理數據,此時的處理數據邏輯會存在多達幾萬次的數據庫變更,當前操作沒有采用切面事務,而是采用框架的AutoCommit自動提交事務,這樣就會造成處理數據時出現幾萬次的創建事務,提交事務,關閉事務,此時造成事務阻塞
解決方案:
1、處理時間較長的操作,如果當前操作中間出現問題對業務沒有影響下次操作時會修正當前業務,這樣的話可以不適用切面事務而是使用框架的AutoCommit提交事務,如果當前操作確實需要保證原子性時,請手動回復數據裝填
2、不要頻繁的開啟、提交事務,采用批量的方式提交事務