java检测tomcat宕机_Tomcat意外宕机分析
之前在網(wǎng)上看過一篇文章,是講Tomcat進程意外退出的,我看完感覺好奇,自己也測試了下,果然是有這種問題,所以自己也借此總結(jié)一下。
先簡單說下測試過程,先創(chuàng)建一個web服務(wù)啟動 test.sh,內(nèi)容如下:
#!/bin/bash
cd/usr/software/tomcat/apache-tomcat-7.0.81/bin/./catalina.sh start
tail-f /usr/software/tomcat/apache-tomcat-7.0.81/logs/catalina.out
然后啟動該腳本,服務(wù)起來了,可以正常訪問。
tomcat啟動之后,當前shell進程并沒有退出,而是掛住在tail進程,往終端輸出日志內(nèi)容。這種情況下:
1)、如果我先直接關(guān)掉ssh窗口后,Java進程會退出,服務(wù)不可用。
2)、而我如果先 用ctrl-c終止test.sh進程,然后再關(guān)閉ssh終端的話,這時Java進程不會退出。服務(wù)沒有受到影響,仍然可用。
3)、下面我又把最后tail這一行去掉,發(fā)現(xiàn)直接關(guān)掉ssh終端窗口,Java進程也不會退出,服務(wù)不受影響。
#!/bin/bash
cd/usr/software/tomcat/apache-tomcat-7.0.81/bin/./catalina.sh start
4)、最后我再次恢復(fù)tail這一行,然后在開頭再加上 set -m,?直接關(guān)掉ssh窗口Java進程同樣也不會退出,服務(wù)同樣也不受影響。
#!/bin/bash
set-m
cd/usr/software/tomcat/apache-tomcat-7.0.81/bin/./catalina.sh start
tail-f /usr/software/tomcat/apache-tomcat-7.0.81/logs/catalina.out
到這里是不是有點暈了,不急,待我慢慢道出原因來。
這是一個有趣的現(xiàn)象,catalina.sh start方式啟動的tomcat會把java進程掛到init(進程id為1)的父進程下,已經(jīng)與當前test.sh進程脫離了父子關(guān)系,也與ssh進程沒有關(guān)系,為什么關(guān)閉ssh終端窗口會導(dǎo)致java進程退出?
經(jīng)過測試,有發(fā)現(xiàn):
a) 用 ctrl-c 終止當前test.sh進程時,系統(tǒng)events進程向 java 和 tail 兩個進程發(fā)送了SIGINT?信號
b) 關(guān)閉ssh終端窗口時,sshd向下游進程發(fā)送SIGHUP, java進程也會收到。
后來通過google后了解到: shell在非交互模式下對后臺進程處理SIGINT信號時設(shè)置的是IGNORE。
交互模式與非交互模式對作業(yè)控制(job control)默認方式不同:
I)在交互模式下,因為作業(yè)控制的需要,shell不會對后臺進程處理SIGINT信號設(shè)置為忽略。因此這樣的話,父進程會把收到的鍵盤事件比如ctrl-c之類的SIGINT傳播給進程組中的每個成員(假設(shè)后臺進程也是父進程組的成員),那么終端隨意ctrl-c就可能導(dǎo)致所有的后臺進程退出,顯然這樣是不合理的。因此,在交互模式下的后臺進程會設(shè)置一個自己的進程組ID。
II)而非交互模式下,通常是不需要作業(yè)控制的,所以作業(yè)控制在非交互模式下默認也是關(guān)閉的(當然也可以在腳本里通過選項set -m打開作業(yè)控制選項)。不開啟作業(yè)控制的話,腳本里的后臺進程可以通過設(shè)置忽略SIGINT信號來避免父進程對組中成員的傳播,因為對它來說這個信號已經(jīng)沒有意義。
在非交互模式下,shell對java進程設(shè)置了SIGINT,SIGQUIT信號設(shè)置了忽略,但并沒有對SIGHUP信號設(shè)為忽略,回頭看上面說的,直接關(guān)閉ssh終端窗口時,sshd向下游進程發(fā)送SIGHUP, java進程也會收到。
再看一下當時的進程層級:
|-sshd(1622)-+-sshd(11681)---sshd(11699)---bash(11700)---test.sh(13285)---tail(13299)
sshd把SIGHUP傳遞給bash進程后,bash會把SIGHUP傳遞給它的子進程,并且對于其子進程test.sh,bash還會對test.sh的進程組里的成員都傳播一遍SIGHUP。因為java后臺進程從父進程catalina.sh(又是從其父進程test.sh)繼承的pgid,所以java進程仍屬于test.sh進程組里的成員,收到SIGHUP后退出。
如果我們在test.sh里設(shè)置開啟作業(yè)控制的話,就不會讓java進程退出了
#!/bin/bash
set-m
cd/usr/software/tomcat/apache-tomcat-7.0.81/bin/./catalina.sh start
tail-f /usr/software/tomcat/apache-tomcat-7.0.81/logs/catalina.out
此時java后臺進程繼承父進程catalina.sh的pgid,而catalina.sh不再使用test.sh的進程組,而是自己的pid作為pgid,catalina.sh進程在執(zhí)行完退出后,java進程掛到了init下,java與test.sh進程就完全脫離關(guān)系了,bash也不會再向它發(fā)送信號。
注: 如果把tail 打印的這一行去掉,為什么Java進程也不會退出,我猜原因應(yīng)該是,如果沒有tail的話, Java進程就不是他們的子進程了,自然怎么操作都不會受影響。
總結(jié)
以上是生活随笔為你收集整理的java检测tomcat宕机_Tomcat意外宕机分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 建设银行贷款利率 中国建设银行的贷款利率
- 下一篇: rdd转换成java数据结构_如何将CS