澳门新葡亰娱乐网站-www.142net-欢迎您

澳门新葡亰娱乐网站是因为你还没有找到一条正确的致富之路,www.142net是将所有的游戏都汇集在一起的官方平台,因为澳门新葡亰娱乐网站这个网站当中有着大量的游戏攻略,托IP定位技术,传达终端直接到达的精准传播方式。

检查Tomcat是否宕机,Tomcat进程意外退出的问题分

来源:http://www.bhtsgq.com 作者:计算机知识 人气:105 发布时间:2019-05-30
摘要:以前在网络看过一篇小说,是讲汤姆cat进度意外退出的,作者看完感到古怪,自己也测试了下,果然是有这种难题,所以自个儿也借此总括一下。 某站点以java开拓,运营在tomcat上,但

  以前在网络看过一篇小说,是讲汤姆cat进度意外退出的,作者看完感到古怪,自己也测试了下,果然是有这种难题,所以自个儿也借此总括一下。

某站点以java开拓,运营在tomcat上,但因某个原因,java时不经常假死只怕机关终止。为了幸免那一个标题,有的时候选用定时检查该站点url的措施判定tomcat的周转状态。其基本思路为:当取获得带jsp后缀文件的url状态码不是200时,强制重启tomcat。用crond每隔一段时间试行壹遍检查。

节前有个别机构的测试蒙受反馈tomcat会意外退出,我们到骨子里条件排查后意识不是jvm crash,日志里有进度销毁的记录,从pause到destory的总体进度:

汤姆cat进度意外退出的难题深入分析

转自:

感激同事宏江投递本稿。

节前某些机构的测试意况反馈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

 

从上边日志来能够看清:

  先轻便说下测试进程,先创立3个web服务运营 test.sh,内容如下:

剧本内容为:

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: 即通过800伍端口发送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 -> destory 
#!/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
  1. #!/bin/bash   
  2.   
  3. n=`curl -I -s   |grep "200 OK" |wc -l`   
  4.   
  5. 检查Tomcat是否宕机,Tomcat进程意外退出的问题分析。    
  6.   
  7. if [ $n -ne 1 ]   
  8.   
  9.   then   
  10.   
  11.    source /etc/profile   
  12.   
  13.    /usr/local/tomcat_push/bin/catalina.sh stop    
  14.   
  15.    /usr/local/tomcat_push/bin/catalina.sh start   
  16.   
  17. fi  

从地方日志来能够判明:

2) tomcat的shutdownhook被触发,推行了销毁逻辑

而那又有二种景况,一是采纳代码里有地点用System.exit来退出jvm,二是系统一发布的功率信号(kill -9除此之外,SIGKILL实信号JVM不会有机会奉行shutdownhook)

先经过排查代码,应用方和中间件团队都排查了System.exit在那些利用中应用的或是。那就只剩余Signal的状态了;经过1番排查后,发现每一次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为一)的父进度下,已经与近期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)

通过内核组伯俞的支援,大家开掘

  然后运转该脚本,服务起来了,能够健康访问。

图片 1

  1. tomcat不是经过脚本正常关闭(viaport: 即通过8005端口发送shutdown指令),因为健康关闭(viaport)的话会在 pause 此前有那样的一句warn日志:
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进程

  tomcat运维将来,当前shell进度并从未退出,而是挂住在tail进度,往终端输出日志内容。这种场所下:

org.apache.catalina.core.StandardServer await
A valid shutdown command was received via the shutdown port. Stopping the Server instance.
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)、借使自个儿先直接关闭ssh窗口后,Java进度会脱离,服务不可用。

下一场才是 pause -> stop -> destory

  1. tomcat的shutdownhook被触发,实施了销毁逻辑,而那又有二种景况,1是行使代码里有地点用System.exit来退出jvm,2是系统一发布的时域信号(kill -玖除却,SIGKILL实信号JVM不会有空子奉行shutdownhook)。
1) 为什么SIGINT (kill -二) 不会让tomcat进程退出?

  二)、而自己1旦先 用ctrl-c终止test.sh经过,然后再关闭ssh终端的话,那时Java进度不会退出。服务未有遭逢震慑,仍旧可用。

先经过排查代码,应用方和中间件团队都排查了System.exit在那一个动用中运用的只怕。那就只剩下Signal的境况了;经过壹番排查后,意识每一遍tomcat意外退出的时刻与ssh会话甘休的时日正好适合。

2) 为什么SIGHUP (kill -1) 会让tomcat进程退出?

本身先是影响只怕是jvm在少数参数下(或因为有些jni)对os的数字信号管理会不一样,看了眨眼间间用到的jvm参数,未有看出难题,也免去了tomcat使用apr/tcnative的状态。

咱俩看一下暗许意况下,jvm进度对SIGINTSIGHUP是怎么管理的,用scala的repl模拟一下:

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

对这一个java进程分别用kill -2kill -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的因由。

  3)、上面作者又把最后tail这一行去掉,发掘一向关闭ssh终端窗口,Java进度也不会脱离,服务不受影响。

有了这几个线索之后,霎时看了1晃对方测试情形的台本,简化后如下:

SIGINT (kill -贰) 不会让后台java进程退出的由来

为了方便,我们用sleep来效仿进度,当大家在彼此形式下:

$ sleep 1000 & 

$ ps -opid,pgid,ppid,stat,cmd -C sleep
  PID  PGID  PPID STAT CMD
 9897  9897  9813 S    sleep 1000   

注意,进程sleep 1000的pid与pgid(进度组)是同一的,那时大家用kill -2是能够杀死sleep 1000进程的。

明日我们把sleep进度放到1个剧本里后台推行:

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

运转a.sh脚本之后,sleep 4400经过的pid与pgid是不一致的,pgid是其父进程的id,即现已淡出了的a.sh进度

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

此时大家用kill -2是杀不掉sleep 4400进程的。

到了这一步,已经十三分临近原因了,一定是shell对后台进程signal_handler做了怎么动作。少明完结了1个自定handler的指令看看是否对kill -2有效:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void my_handler(int sig) {
    printf("handler aaan");
    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

本文由澳门新葡亰发布于计算机知识,转载请注明出处:检查Tomcat是否宕机,Tomcat进程意外退出的问题分

关键词: 程序员 邦仁聊技术

上一篇:基于jenkins的持续集成

下一篇:没有了

最火资讯