一次信号量引起的tomcat异常退出

 

近期在玩大数据。有个朋友找过来,说他线上的tomcat会莫名其妙的退出,表示很是苦恼,请我帮看看。每次他发现退出了,都经过腾讯云的WEB控制台登陆,启动tomcat。java

本着助人为乐(shao kao hao chi)的精神,我连上去开始分析。首先确定是看tomcat的日志,看看有没有记录到相关信息,是什么途径退出的。linux

从日志上看,tomcat收到了退出请求,并按照要求关闭容器。那么是否能够认为是有人执行了shutdown.sh呢?并不能。执行了shutdown脚本的关闭日志是这样的。apache

与其相关的tomcat源码截图以下。截图左侧有行号。windows

tomcat启动时,设置await,等待关闭指令进入。org\apache\catalina\startup\Bootstrap.java tomcat

catalinaDaemon的定义以下。bash

 org\apache\catalina\startup\Catalina.java服务器

 

具体实例化时,会将接口Server的实例指向StandardServer。类路径以下。函数

org\apache\catalina\Server.java学习

org\apache\catalina\core\StandardServer.java测试

而StandServer中的输出相关日志的源码以下: 

 读取的配置文件为org\apache\catalina\core\LocalStrings.properties

当tomcat收到正经的关闭指令时,会输出此日志,说明是收到指令关闭容器。

 正经的指令关闭容器,相关代码以下。

那么,如今的证听说明,这个tomcat不是经过SHUTDOWN报文关闭的。并且,从下图来看,也颇能说明这个SHUTDOWN指令不是这么容易发成功的。

那么如今可能性最大的办法就是经过KILL指令来操做。执行bash脚本须要登陆机器,那么从wtmp、utmp查找一下这个时间点的登陆记录呢?

下面是IPIP的结果。

 

 换言之,23日早上tomcat异常退出的时候,有一个来自腾讯云的BGP机房的地址也巧合的断开了会话。而我这个朋友的机器就放在腾讯云。有点奇怪是吗?

继续追查,连续追溯几天的tomcat日志,比对utmp、wtmp结果,再比对IPIP结果,都是如此。来自腾讯云BGP机房的会话断开,tomcat同一时间点退出。精确到秒级。连续多天出现不少次,说明tomcat退出和WEB会话退出是具有因果关系的。

通过询问,朋友确认他是习惯于使用WEB控制台的方式登陆服务器,启动了tomcat之后就丢在一边,开始调试接口了。那么有什么可能会致使这样的因果关系出现?这就要说到Linux系统的一个历史悠久的进程间通讯的机制——信号量。

具体信号量是什么,请自行查询相关资料了解学习。针对本次问题,能够简单的理解为进程间通信的一种机制。

进程A须要进程B作点事,而进程间的内存区域某种意义上说是互不可见的。这个时候就须要经过信号量来完成。进程A能够按照预先定义的信号量规范向进程B发出信号量,当进程B收到后,根据具体信号量的值决定处理逻辑。具体信号量清单,能够在命令行经过以下命令查询。命令中均为字母,没有数字1。

这其中最多见的就是9,SIGKILL。当进程收到此信号量时,会被KILL掉。此信号量由操做系统处理,应用不能处理。在vista以前的windows系统中,是有办法渗透到内核中的。此时能够拦截相似WM_CLOSE之类的消息,让某个程序没法关闭。到了win七、win10时代,已经不能使用此类技巧了。

此外,咱们熟悉的CTRL + C操做,发出的是SIGINT。有些场景下,咱们须要通知程序优雅的退出,此时能够发出SIGQUIT,也就是kill -3。

那么WEB控制台会话断开,会发出什么信号量呢?咱们来试试就知道了。Java虽说不能操做系统底层,可是sun.misc包有惊喜哦。代码以下。

 

如图所示,这段代码会在收到信号量时输出线程名称,信号量名称,并翻译成具体的数字。随后,在main函数中,我“注册”了HUP、INT、ABRT、TERM四种信号量。注册四种是由于不清楚具体会发什么出来,索性有可能的都搞起来。

编译,打包。此处有一个问题须要注意,因为信号量属于操做系统底层机制,每一个不一样操做系统所支持的信号量是不一样的,JVM中经过private static native int findSignal(String paramString)提供支持。native方法涉及具体VM实现,不贴代码了。不过很容易想到的是,windows和linux固然不一样。因此此处就要在上位机编写,下位机调试了。windows底下运行报错可不要慌张哦。

接下来的事情就简单了。把程序上传服务器,经过WEB控制台登陆服务器,将执行结果重定向到文本文件中,而后静待控制台超时。结果以下。

结果不用再分析了,WEB控制台会在退出时发出SIGHUP,至关于kill -1。而tomcat在收到SIGHUP会怎么操做呢?小伙伴们能够试试看kill -1 pid,再看看日志,就明白了。

解决方案其实也简单。SIGHUP是HANG UP的意思,能够用nohup xx.sh &来完全屏蔽SIGHUP和SIGINT。另外,通过测试发现,经过单击SecureCRT的tab页右侧的×也能够触发信号量,而直接logout或者点菜单上的红叉则并不会触发。

感兴趣的小伙伴能够把这个程序扩展一下,测测看。说不定你的异常退出问题也能迎刃而解呢。

此问题的解决离不开上海中通的刘建刚同窗,特此致谢。

相关文章
相关标签/搜索