亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Web服務器 > 正文

關于 Tomcat進程意外退出的問題解析

2024-09-01 13:49:23
字體:
來源:轉載
供稿:網友

節前某個部門的測試環境反饋tomcat會意外退出,我們到實際環境排查后發現不是jvm crash,日志里有進程銷毀的記錄,從pause到destory的整個過程:

org.apache.coyote.AbstractProtocol pause
Pausing ProtocolHandler
org.apache.catalina.core.StandardService stopInternal
Stopping service Catalina
org.apache.coyote.AbstractProtocol stop
Stopping ProtocolHandler
org.apache.coyote.AbstractProtocol destroy
Destroying ProtocolHandler

從上面日志來可以判斷:

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/bashcd /data/server/tomcat/bin/./catalina.sh starttail -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進程退出?

我們的推測是ssh窗口在關閉時,對當前交互的shell以及正在運行的test.sh等子進程發送某個退出的Signal,找了一臺裝有systemtap的機器來驗證,所用的stap腳本是從澗泉同學那里copy的:

function time_str: string () {return ctime(gettimeofday_s() + 8 * 60 * 60);}probe begin {printdln(" ", time_str(), "BEGIN");}probe end {printdln(" ", time_str(), "END");}probe signal.send {if (sig_name == "SIGHUP" || sig_name == "SIGQUIT" || sig_name=="SIGINT" || sig_name=="SIGKILL" || sig_name=="SIGABRT") {printd(" ", time_str(), sig_name, "[", uid(), pid(), cmdline_str(), "] -> [", task_uid(task), sig_pid, pid_name, "], ");task = pid2task(pid());while (task_pid(task) > 0) {printd(" ", "[", task_uid(task), task_pid(task), task_execname(task), "]");task = task_parent(task);}println("");}}

模擬時的進程層級(pstree)大致如下,tomcat啟動后java進程已經脫離test.sh,掛在init下:

|-sshd(1622)-+-sshd(11681)---sshd(11699)---bash(11700)---test.sh(13285)---tail(13299)

經過內核組伯俞的協助,我們發現

a) 用 ctrl-c 終止當前test.sh進程時,系統events進程向 java 和 tail 兩個進程發送了SIGINT 信號

SIGINT [ 0 11 ] -> [ 0 20629 tail ] SIGINT [ 0 11 ] -> [ 0 20628 java ] SIGINT [ 0 11 ] -> [ 0 20615 test.sh ] 

注pid 11是events進程

b) 關閉ssh終端窗口時,sshd向下游進程發送SIGHUP, 為何java進程也會收到?

SIGHUP [ 0 11681 sshd: hongjiang.wanghj [priv] ] -> [ 57316 11700 bash ] SIGHUP [ 57316 11700 -bash ] -> [ 57316 11700 bash ]SIGHUP [ 57316 11700 ] -> [ 0 13299 tail ] SIGHUP [ 57316 11700 ] -> [ 0 13298 java ] SIGHUP [ 57316 11700 ] -> [ 0 13285 test.sh ] 

不過伯俞很忙沒有繼續協助分析這個問題(他給出了一些猜測,但后來證明并不是那樣)。

確定了是由signal引起的之后,我的疑惑變成了:

1) 為什么SIGINT (kill -2) 不會讓tomcat進程退出?

2) 為什么SIGHUP (kill -1) 會讓tomcat進程退出?

我第一反應可能是jvm在某些參數下(或因為某些jni)對os的信號處理會不同,看了一下應用的jvm參數,沒有看出問題,也排除了tomcat使用apr/tcnative的情況。

我們看一下默認情況下,jvm進程對SIGINT和SIGHUP是怎么處理的,用scala的repl模擬一下:

scala> Runtime.getRuntime().addShutdownHook(new Thread() { override def run() { println("ok") } })

對這個java進程分別用kill -2和kill -1發現都會導致jvm進程退出,并且也觸發shutdownhook。這也符合oracle對hotspot虛擬機處理Signal的說明,參考這里,SIGTERM,SIGINT,SIGHUP三種信號都會觸發shutdownhook

看來并不是jvm的事,繼續猜測是否與進程的狀態有關?catalina.sh腳本里并沒有使用start-stop-daemon之類的方式啟動java進程,start參數的執行方式簡化后腳本相當于:

eval '"/pathofjdk/bin/java"' 'params' org.apache.catalina.startup.Bootstrap start '&'

就是簡單的把java放到后臺執行。當catalina.sh自身進程退出后,java進程的ppid變成了1

花了很多的時間猜測可能是OS層面的原因,后來發現并沒有關系。春節后回來讓少明和澗泉也一起分析這個問題,因為他們有c的背景,對系統底層知道的多一些,用了大半天時間,不斷猜測和驗證,最后確認了是Shell的原因。

SIGINT (kill -2) 不會讓后臺java進程退出的原因

為了簡便,我們用sleep來模擬進程,當我們在交互模式下:

$ sleep 1000 & $ ps -opid,pgid,ppid,stat,cmd -C sleepPID PGID PPID STAT CMD9897 9897 9813 S sleep 1000 

注意,進程sleep 1000的pid與pgid(進程組)是相同的,這時我們用kill -2是可以殺掉sleep 1000進程的。

現在我們把sleep進程放到一個腳本里后臺執行:

$ cat a.sh#!/bin/shsleep 4400 &echo "shell exit"

運行a.sh腳本之后,sleep 4400進程的pid與pgid是不同的,pgid是其父進程的id,即已經退出了的a.sh進程

$ ps -opid,pgid,ppid,comm -p 63376PID PGID PPID COMM63376 63375 1 sleep

這時我們用kill -2是殺不掉sleep 4400進程的。

到了這一步,已經非常接近原因了,一定是shell對后臺進程signal_handler做了什么手腳。少明實現了一個自定handler的命令看看是否對kill -2有效:

#include <stdio.h>#include <signal.h>#include <stdlib.h>void my_handler(int sig) {printf("handler aaa/n");exit(0);}int main() {signal(SIGINT, my_handler);for(;;) { }return 0;}

我們把編譯后的a.out命令在腳本里以后臺方式運行:

$ cat a.sh#!/bin/sh/tmp/a.out &

這次再嘗試用kill -2去殺a.out進程,是可以的。這說明shell對signal_handler做手腳是在執行用戶邏輯之前,也就是腳本在fork出子進程的時候就設置了。按照這個線索我們google后了解到: shell在非交互模式下對后臺進程處理SIGINT信號時設置的是IGNORE。

交互模式與非交互模式對作業控制(job control)默認方式不同

為什么在交互模式下shell不會對后臺進程處理SIGINT信號設置為忽略,而非交互模式下會設置為忽略呢?還是比較好理解的,舉例來說,我們先某個前臺進程運行時間太長,可以ctrl-z中止一下,然后通過bg %n把這個進程放入后臺,同樣也可以把一個cmd &方式啟動的后臺進程,通過fg %n放回前臺,然后在ctrl-c停止它,當然不能忽略SIGINT。

為何交互模式下的后臺進程會設置一個自己的進程組ID呢?因為默認如果采用父進程的進程組ID,父進程會把收到的鍵盤事件比如ctrl-c之類的SIGINT傳播給進程組中的每個成員,假設后臺進程也是父進程組的成員,因為作業控制的需要不能忽略SIGINT,你在終端隨意ctrl-c就可能導致所有的后臺進程退出,顯然這樣是不合理的;所以為了避免這種干擾后臺進程設置為自己的pgid。

而非交互模式下,通常是不需要作業控制的,所以作業控制在非交互模式下默認也是關閉的(當然也可以在腳本里通過選項set -m打開作業控制選項)。不開啟作業控制的話,腳本里的后臺進程可以通過設置忽略SIGINT信號來避免父進程對組中成員的傳播,因為對它來說這個信號已經沒有意義。

回到tomcat的例子,catalina.sh腳本通過start參數啟動的時候,就是以非交互方式后臺啟動,java進程也被shell設置了忽略SIGINT信號,因此在ctrl-c結束test.sh進程時,系統發送的SIGINT對java沒有影響。

SIGHUP (kill -1) 讓tomcat進程退出的原因
在非交互模式下,shell對java進程設置了SIGINT,SIGQUIT信號設置了忽略,但并沒有對SIGHUP信號設為忽略。再看一下當時的進程層級:

|-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里設置開啟作業控制的話,就不會讓java進程退出了

#!/bin/bashset -m cd /home/admin/tt/tomcat/bin/./catalina.sh starttail -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也不會再向它發送信號。

以上所述是小編給大家介紹的關于 Tomcat進程意外退出的問題解析,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美激情在线视频| 最近免费中文字幕视频2019| 日韩精品免费看| 另类视频在线观看| 性欧美视频videos6一9| 国产综合在线视频| 91中文在线观看| 91久久精品美女| 国产日韩欧美中文| 精品中文字幕在线2019| 国自产精品手机在线观看视频| 清纯唯美日韩制服另类| 欧美激情久久久| 日韩在线观看视频免费| 日韩精品在线观看网站| 久久久久久18| 国产一区二区三区丝袜| 北条麻妃一区二区在线观看| 日韩免费电影在线观看| 欧美视频一二三| 国产精品久久国产精品99gif| 欧美视频在线观看免费网址| 69久久夜色精品国产69乱青草| 亚洲欧洲av一区二区| 欧美一级免费视频| 国产精品麻豆va在线播放| 欧美精品第一页在线播放| 欧美色另类天堂2015| 久久视频中文字幕| 欧美亚洲日本黄色| 久久亚洲精品一区二区| 久久人体大胆视频| 久久91亚洲精品中文字幕| 国产日韩中文在线| 精品中文字幕视频| 国产精品极品尤物在线观看| 国产欧美精品va在线观看| 国产精品免费在线免费| 欧美中文字幕在线| 国产精品福利网| 国产精品∨欧美精品v日韩精品| 国产69精品久久久久99| 97精品伊人久久久大香线蕉| 欧美日韩电影在线观看| 欧美华人在线视频| 自拍偷拍亚洲区| 国产精品久久av| 欧美一区二区视频97| 日韩精品免费在线视频| 欧美与黑人午夜性猛交久久久| 色综合伊人色综合网站| 九九九久久国产免费| 欧美日本高清视频| 欧美中文字幕视频在线观看| 亚洲国产91色在线| 在线观看久久av| 在线电影中文日韩| 色天天综合狠狠色| 国产午夜精品全部视频在线播放| 欧美成人精品一区二区| 日本一区二区三区在线播放| 综合av色偷偷网| 亚洲网在线观看| 日韩精品亚洲元码| 97在线视频免费观看| 亚洲毛茸茸少妇高潮呻吟| 国产欧美精品xxxx另类| 久久伊人精品视频| 国产香蕉一区二区三区在线视频| 另类色图亚洲色图| 日韩国产欧美精品一区二区三区| 欧美精品免费看| 国产精品久久久久国产a级| 久久综合网hezyo| 国产精品一区二区三区免费视频| 欧美大片网站在线观看| **欧美日韩vr在线| 国产成人激情小视频| 性欧美长视频免费观看不卡| 欧美亚洲成人精品| 国产精品揄拍500视频| 亚洲精品福利免费在线观看| 日韩av影院在线观看| 亚洲视频综合网| 欧美床上激情在线观看| 国产主播喷水一区二区| 国产欧美一区二区三区在线| 日韩欧美成人免费视频| 97视频色精品| 欧美www在线| 久久伊人色综合| 欧美视频在线观看免费网址| 欧美精品videos另类日本| 亚洲国产精品成人va在线观看| 欧美在线视频一区二区| 亚洲成人av在线播放| 亚洲网址你懂得| 亚洲精品久久久一区二区三区| 5566日本婷婷色中文字幕97| 日本免费久久高清视频| 色悠悠久久久久| 韩国欧美亚洲国产| 成人欧美一区二区三区在线| 欧美久久精品一级黑人c片| xxxxxxxxx欧美| 午夜精品久久久久久久久久久久久| 亚洲精品免费一区二区三区| 亚洲免费视频一区二区| 亚洲社区在线观看| 国产自摸综合网| 欧美高清在线播放| 大胆人体色综合| 日韩国产精品视频| 欧美人在线视频| 最新91在线视频| 日韩高清不卡av| 97色在线视频观看| 日韩精品极品毛片系列视频| 国产精品自拍网| 久久久精品一区二区三区| 91精品久久久久久久久青青| 国产精品视频永久免费播放| 18一19gay欧美视频网站| 在线观看久久av| 国产亚洲欧洲黄色| 日韩欧美国产中文字幕| 成人网在线观看| 欧美色视频日本版| 亚洲国产天堂久久国产91| 久久免费视频在线观看| 国产一区二区三区在线视频| 久久精品国产视频| 欧美在线视频a| www.美女亚洲精品| 久久精品久久久久久国产 免费| 91伊人影院在线播放| 久久久国产一区二区三区| 国产亚洲精品美女| 国产精品pans私拍| 亚洲男人天堂古典| 一本色道久久88亚洲综合88| 欧美亚洲国产另类| 久久久精品亚洲| 亚洲国产精品字幕| 亚洲精品狠狠操| 久久琪琪电影院| 亚洲一区第一页| 亚洲精品wwwww| 国产精品人人做人人爽| 欧美电影在线观看高清| 中文字幕一区电影| 精品久久久久久亚洲精品| 色爱av美腿丝袜综合粉嫩av| 亚洲香蕉成视频在线观看| 伊人亚洲福利一区二区三区| 78m国产成人精品视频| 成人福利在线观看| 日韩欧美在线视频观看| 色综合伊人色综合网| 在线免费看av不卡| 国产精品香蕉av| 欧美日韩亚洲精品一区二区三区| 欧美大成色www永久网站婷| 黑人巨大精品欧美一区免费视频|