tomcat進程意外退出的問題分析


1) tomcat不是通過腳本正常關閉(viaport: 即通過8005端口發送shutdown指令)

因為正常關閉(viaport)的話會在 pause 之前有這樣的一句warn日志:

    org.apache.catalina.core.StandardServer await
    A valid shutdown command was received via the shutdown port. Stopping the Server instance.
    然后才是 pause -> stop -> destroy 
2) tomcat的shutdownhook被觸發,執行了銷毀邏輯

而這又有兩種情況,一是應用代碼里有地方用System.exit來退出jvm,二是系統發的信號(kill -9除外,SIGKILL信號JVM不會有機會執行shutdownhook)

先通過排查代碼,應用方和中間件團隊都排查了System.exit在這個應用中使用的可能。那就只剩下Signal的情況了;經過一番排查后,發現每次tomcat意外退出的時間與ssh會話結束的時間正好吻合。

有了這個線索之后,銀時同學立刻看了一下對方測試環境的腳本,簡化后如下:

$ cat test.sh
#!/bin/bash
cd /data/server/tomcat/bin/
./catalina.sh start
tail -f /data/server/tomcat/logs/catalina.out

tomcat啟動為后,當前shell進程並沒有退出,而是掛住在tail進程,往終端輸出日志內容。這種情況下,如果用戶直接關閉ssh終端的窗口(用鼠標或快捷鍵),則java進程也會退出。而如果先ctrl-c終止test.sh進程,然后再關閉ssh終端的話,則java進程不會退出。

這是一個有趣的現象,catalina.sh start方式啟動的tomcat會把java進程掛到init(進程id為1)的父進程下,已經與當前test.sh進程脫離了父子關系,也與ssh進程沒有關系,為什么關閉ssh終端窗口會導致java進程退出?

 

如果我們在test.sh里設置開啟作業控制的話,就不會讓java進程退出了

#!/bin/bash
set -m  
cd /home/admin/tt/tomcat/bin/
./catalina.sh start
tail -f /home/admin/tt/tomcat/logs/catalina.out

此時java后台進程繼承父進程catalina.sh的pgid,而catalina.sh不再使用test.sh的進程組,而是自己的pid作為pgid,catalina.sh進程在執行完退出后,java進程掛到了init下,java與test.sh進程就完全脫離關系了,bash也不會再向它發送信號。

詳情參考:http://hongjiang.info/why-kill-2-cannot-stop-tomcat/,寫的很詳細。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM