【致远FAQ】致远OA宕机之Tomcat异常宕机

【致远FAQ】致远OA宕机之Tomcat异常宕机问题描述tomcat进程已经不在; 由于在启动命令行参数中增加了相关的日志监控,重点查找JVM内存溢出、jvm的crash的日志进行问题定位; 没有.hprof文件生成【基本可以推论没有出现JVM内存溢出】 没有hs_err_xxx.log文件生成【基本可以推论JVM没有出现严重的crash异常】问题分析1)通过catalina.log看出tomcat出现了非正常关闭操作下的停机;如果是正常停机会在输出图1的日志前输出如图2所示的内容2)tomcat停机的时..

大家好,又见面了,我是你们的朋友全栈君。

问题描述

  1. tomcat进程已经不在;
  2. 由于在启动命令行参数中增加了相关的日志监控,重点查找JVM内存溢出、jvm的crash的日志进行问题定位;
  3. 没有.hprof文件生成【基本可以推论没有出现JVM内存溢出】
  4. 没有hs_err_xxx.log文件生成【基本可以推论JVM没有出现严重的crash异常】

问题分析

1)通过catalina.log 看出tomcat出现了非正常关闭操作下的停机;如果是正常停机会在输出图1的日志前输出如图2所示的内容

【致远FAQ】致远OA宕机之Tomcat异常宕机

【致远FAQ】致远OA宕机之Tomcat异常宕机

2)tomcat停机的时间发生在15:32:28秒
3)查看应用日志,没有发现存在业务异常;但是佐证了tomcat停机的时间,如图3所示:

【致远FAQ】致远OA宕机之Tomcat异常宕机

4)对比tomcat停机的时间,查看操作系统的日志/var/log/messages在15:32:28相关日志内容,如图4所示,可以得出以下信息:

【致远FAQ】致远OA宕机之Tomcat异常宕机

 5)tomcat宕机、sshd进程收到断开连接的事件都发生在同一秒。

6)该日志中也记录了发出ssh断开连接事件的客户端ip地址(该信息非常有用,可以根据ip地址定位到操作者,并通过操作者了解问题发生前相关操作信息,这为后期的缩小问题范围并将问题复现提供了很有价值的线索)。
7)至此,发现了一个重要线索:tomcat的退出与sshd的session关闭发生在同一时刻;即使是巧合,这个信息也是值得去深究。
8)我们知道,tomcat在以下两种情况下会触发shutdownhook:(1)代码里面执行了System.exit;(2)tomcat进程接收到了除9以外的会引起退出的信号量;我们对第一种情况进行了代码扫描并逐一的排除,不存在业务代码调用System.exit的场景;对于第(2)种场景的排查很显然需要针对tomcat的启动脚本。
9)基于此,根据断开ssh的session会话的ip地址,定位到相应的操作者,获取到当时执行的操作命令项目,了解到采用seeyonupdate脚本执行启动;以下图示是更新脚本片段;从代码片段来看,在启动进程里面增加了一个tail语句。

【致远FAQ】致远OA宕机之Tomcat异常宕机

【致远FAQ】致远OA宕机之Tomcat异常宕机

【致远FAQ】致远OA宕机之Tomcat异常宕机

 10)现在的问题焦点就转移到,原有启动脚本里面增加了一行tail语句导致tomcat异常退出的原因:从脚本的执行过程来看,tomcat启动后,当前shell进程并没有退出,而是挂在tail进程上。这种情况下,如果用户直接关闭ssh终端的窗口,sshd会把SIGHUP信号传递给bash进程,bash会把SIGHUP传递给seeyonupdate进程及该进程所属的进程组的所有进程成员。(java后台进程继承了父进程startup.sh的pgid,所以java进程仍属于进程组里的成员,收到SIGHUP后会退出。

原因定位

综合以上过程的分析,我们可以把整个tomcat异常退出的流程串联一下:
1)操作用户在ssh终端执行了seeyonupdate脚本,对综合办公应用平台进行升级部署与启动;脚本的最后,通过执行tail命令,对日志信息进行查看(此时,seeyonupdate脚本并未退出,而是挂在了tail进程上)
2)用户关闭了ssh终端窗口或网络断开导致ssh连接断开,sshd会把SIGHUP信号发给了窗口内的bash进程,bash进程会把SIGHUP传递给seeyonupdate进程及该进程所属的进程组的所有进程成员。(java后台进程继承了父进程startup.sh的pgid,所以java进程仍属于进程组里的成员,也会收到SIGHUP信号)
Tomcat收到SIGHUP信号后,会激活SIGHUP handler线程(如图6所示);该线程会触发Tomcat的shutdownhook函数(如图7所示),在该函数中会执行tomcat退出时的资源销毁操作(如图8所示):

【致远FAQ】致远OA宕机之Tomcat异常宕机

图6 jstack堆栈快照

【致远FAQ】致远OA宕机之Tomcat异常宕机

图7 jstack堆栈快照

 【致远FAQ】致远OA宕机之Tomcat异常宕机

 图8 ctp.log日志片段

修改与建议

        该问题的解决,也能解释之前项目现场其他环境下没有异常日志生成,却出现了tomcat异常宕机的情况。

技术方面

方法1:只需要在tail命令后面加&,把tail命令转后台执行,让seeyonupdate进程正常退出

【致远FAQ】致远OA宕机之Tomcat异常宕机

方法2:在seeyonupdate对应的脚本中,增加“set -m”,开启作业控制

 【致远FAQ】致远OA宕机之Tomcat异常宕机

 针对这两种修改方法进行了验证,tomcat的进程不会销毁

管理方面

1)建立对运维脚本的代码审查过程;
2)对于运维脚本加强多场景下的功能测试。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163641.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月23日 上午6:16
下一篇 2022年7月23日 上午6:16


相关推荐

  • 2019 年MySQL面试题及答案

    2019 年MySQL面试题及答案

    2022年2月10日
    35
  • c++ string类字符串查找

    c++ string类字符串查找1 find 函数 find 函数用于在 string 字符串中查找子字符串出现的位置 它其中的两种原型为 size tfind conststring amp str size tpos 0 const size tfind constchar s size tpos 0 const 第一个参数为待查找的子字符串 它可以是 string 字符串 也可以是 C 风格的字符串 第二个参数为开始查找的位置 下标 如果不指明 则从第 0 个字符开始查找 请看下面的

    2026年3月16日
    2
  • Discuz 二次开发 (一) 目录结构和运行逻辑

    Discuz 二次开发 (一) 目录结构和运行逻辑Discuz二次开发(一)目录结构和运行逻辑目录结构DISCUZ使用自己的框架,与现在主流的web框架不同,DISCUZ没有路由表,他的路由是由入口文件来实现的。apiuc.phpUCenter通信文件/api/addons应用中心/api/connect通讯互联/api/googleGoogle引擎结构处理/api/javascript数据和广告的js调用/api/manyoumanyou应用及搜索等相关服务/api/remote远程更新/api/tr

    2022年5月19日
    43
  • loadrunner压力测试学习笔记

    loadrunner压力测试学习笔记loadrunner学习过程以下仅记录自己的学习过程,有不对之处欢迎指出。压力测试步骤:1.分析需求2.准备脚本3.调试脚本2.准备脚本:可以录制也可以自己写,录制的话先按需求分好每一个action,录制时先切换到当前action,再进行录制。例如:创建一个新的脚本,在action里添加新的action,open_index,submit_login,sign_off(loadrunner自带案例的登录过程)3.调试脚本:(1)回放:脚本准备好后进行回放,需要参数的提前准备好参数,比如注册

    2022年7月18日
    17
  • 数据可视化工具d3与echarts的区别

    数据可视化工具d3与echarts的区别数据可视化工具d3与echarts的区别

    2022年4月23日
    270
  • python常用模块大全_python常用第三方模块大全

    python常用模块大全_python常用第三方模块大全mathmath.ceil(a):用来返回≥a的最小整数math.floor(a):用来返回≤a的最大整数round(a[,b])如果没有参数b,只有a,round()作用是四舍五入如果

    2022年7月28日
    10

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号