问题解决:遇到tomcat的假死问题,如何排查问题

2024-08-28 12:48

本文主要是介绍问题解决:遇到tomcat的假死问题,如何排查问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 问题场景
  • 问题环境
  • 问题原因
  • 排查过程
    • 查看tomcat的gc情况
    • 排查内存泄露问题
    • HashMap死锁
    • CLOSE_WAIT过多情况
  • 总结
  • 参考链接
  • 参考图
    • JVM结构
    • TCP的三次握手和四次挥手
  • 随缘求赞

问题场景

线上,有时候会遇到一种这样的情况:tomcat没有奔溃退出,输出日志也没有异常,但是界面访问就一直卡着。假如遇到这种情况,没错,你遇到了tomcat假死问题了。那么,该怎么排查这个问题呢?这个就是本文的重点了。

在这里插入图片描述

问题环境

软件版本
tomcat7.0
JDK1.6
Centos6

问题原因

在这里插入图片描述

tomcat假死的原因有多种,这里罗列博主遇到的几种情况:

  1. HashMap死锁
  2. 内存泄露
  3. CLOSE_WAIT过多

排查过程

遇到这种tomcat假死的情况,先不着急重启应用,先排查一下。

在这里插入图片描述

以下是博主之前操作的过程:

查看tomcat的gc情况

使用以下命令拿到对应的gc情况,命令如下:

jmap -heap pid >> jvm_memory.log

这个命令,主要是打印堆摘要,其中包括使用的GC算法、堆配置和生成堆使用情况等。博主生成的文件当中,关于GC部分如下:

using thread-local object allocation.
Parallel GC with 16 thread(s)Heap Configuration:MinHeapFreeRatio = 40MaxHeapFreeRatio = 70MaxHeapSize      = 3221225472 (3072.0MB)NewSize          = 2686976 (2.5625MB)MaxNewSize       = -65536 (-0.0625MB)OldSize          = 5439488 (5.1875MB)NewRatio         = 2SurvivorRatio    = 8PermSize         = 134217728 (128.0MB)MaxPermSize      = 268435456 (256.0MB)Heap Usage:
PS Young Generation
Eden Space:capacity = 935133184 (891.8125MB)used     = 171217136 (163.28538513183594MB)free     = 763916048 (728.5271148681641MB)18.309385115350587% used
From Space:capacity = 68878336 (65.6875MB)used     = 41388552 (39.47119903564453MB)free     = 27489784 (26.21630096435547MB)60.089361043797574% used
To Space:capacity = 67174400 (64.0625MB)used     = 0 (0.0MB)free     = 67174400 (64.0625MB)0.0% used
PS Old Generationcapacity = 2147483648 (2048.0MB)used     = 2142115640 (2042.8806686401367MB)free     = 5368008 (5.119331359863281MB)99.75003264844418% used
PS Perm Generationcapacity = 161087488 (153.625MB)used     = 159574696 (152.18228912353516MB)free     = 1512792 (1.4427108764648438MB)99.06088795673566% used

从输出结果,我们可以看到目前是在进行GC操作。

在这里插入图片描述

另外,我们也可以使用命令jstat来查看,命令如下:

jstat  -gcutil pid 250 7

说明:
pid: 进程号
250:间隔时间,单位为毫秒
7: 输出次数,这里指输出7次

因为当时排查的时候,没有使用这个命令。等问题解决了,才发现有这个命令,没办法复现当时的情况。

在这里插入图片描述

为了给大家讲解一下,就运行此命令,展示当前应用的情况:

S0S1EOPYGCYGCTFGCFGCTGCT
0.000.0082.1584.9499.84503885413.400287018355.98523769.385
0.000.0086.0884.9499.84503885413.400287018355.98523769.385
0.000.0090.8684.9499.84503885413.400287018355.98523769.385
0.000.0093.8884.9499.84503885413.400287018355.98523769.385
0.000.0097.5484.9499.84503885413.400287018355.98523769.385
23.600.005.9684.9499.84503895413.476287018355.98523769.461
23.600.0021.1984.9499.84503895413.476287018355.98523769.461

说明:下面是各个选项的含义

说明
S0Heap上的 Survivor space 0 段已使用空间的百分比
S1Heap上的 Survivor space 1 段已使用空间的百分比
EHeap上的 Eden space 段已使用空间的百分比
OHeap上的 Old space 段已使用空间的百分比
PPerm space 已使用空间的百分比
YGC从程序启动到采样时发生Young GC的次数
YGCTYoung GC所用的时间(单位秒)
FGC从程序启动到采样时发生Full GC的次数
FGCT完整的垃圾收集时间(单位秒)
GCT总垃圾收集时间(单位秒)

排查内存泄露问题

一般应用运行了很久,突然才出现问题,可能是有几个原因:

  1. 外部原因的变化,如远程服务异常;
  2. 内部原因的变化,如升级代码存在问题等。

一般针对内存泄露,除了开发代码的时候,就进行规范之后,等运行之后,要查看该问题,特别是线上环境的话,最好将完整的JVM堆栈信息dump下来。这个时候可以使用以下命令:

jmap -dump,format=b,file=heap-dump.bin <pid>

这个命令的作用为:将hprof二进制格式的Java堆转储到filenamelive子选项是可选的。如果指定,则只转储堆中的活动对象。要浏览堆转储,可以使用jhat(Java堆分析工具)读取生成的文件。

在这里插入图片描述

转换的文件比较大,一般有几个GB。所以要从现场环境拿下来,肯定得先进行压缩,然后再下载。这里我推荐使用JProfiler来进行JVM分析。关于JProfiler,请自行搜索使用。

在这里插入图片描述

使用JProfiler打开head-dump.bin文件,就可以看到一个很明显的东西,截图如下:

在这里插入图片描述

在上图可以知道,在Classes页面,有一个类路径下面,生成了很多对象。我们点击Biggest Objects,截图如下:

在这里插入图片描述

从上图可以知道,有一个对象非常大,占据了1487MB。而从第一步拿到的堆栈信息,整个堆栈最大是3072.0MB。所以,初步可以判断是因为这个东西,导致了频繁的GC,进行导致tomcat假死。

在这里插入图片描述

通过咨询项目运维成员,说该对象属于以前的插件-听云,属于端对端监控的插件。该插件之前要下线的,但是没有执行成功。所以该插件目前还运行着。而最近听云服务器正式下线,所以导致tomcat连接听云出现问题。暂时锁定该问题,所以先安排运维人员移除该插件,并重启tomcat。其中也遇到一个问题,并形成博客《问题解决:启动tomcat,日志输出:java.lang.ClassNotFoundException: com.tingyun.api.agent.TingYunApiImpl》,有兴趣的小伙伴可以看看。

重启之后,目前运行将近一周了,还未发现tomcat假死现象。所以,可以肯定,这个插件是造成近期应用假死的元凶。

在这里插入图片描述

这个原因是属于近期频繁假死的真凶,但是运维人员反映,该应用在之前是会出现这种tomcat假死的情况的。只是频率不会像现在一天两次的情况,一般是数周会发生一次。所以,还是得继续排查。

在这里插入图片描述

HashMap死锁

在应用运行一段时间之后,使用阿里巴巴开源的arthas来进行问题排查。这个是排查Java问题的利器。关于arthas的使用,请自行登录官网查看。

在这里插入图片描述

登录机器,使用arthas连接应用,查看当前的线程情况,发现有意思的一幕,截图如下:

在这里插入图片描述

有两个线程一直挂着,没有退出过。通过命令thread查看该线程具体情况,截图如下:

在这里插入图片描述

如果曾经遇到过这个问题的话,应该可以知道,这个就是所谓的HashMap死锁问题。这个需要去查看具体的代码,查看为什么会发生死锁的问题。

在这里插入图片描述

从这个可以得到,假如这个HashMap死锁发生的频率不高,但是随着时间的推移,这种情况不断发生,就会将全部的连接给占据了,导致了tomcat没可用连接进行响应,就会导致tomcat假死的情况发生。这个就是为什么之前应用发生死锁的频率比较低,要数周才可能会发生一次。

在这里插入图片描述

CLOSE_WAIT过多情况

在实际场景,我们也会发现一种情况,tomcat假死的时候,使用以下命令获取TCP连接情况:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

结果如下(命令可能和截图不同,因为这个是进行筛选并定时执行得到的):

在这里插入图片描述

可以看到,目前存在很多的CLOSE_WAIT。这个是因为服务端未及时释放资源。关于这个问题,除了可以修改Linux配置,我们也可以直接修改tomcat的配置文件,禁用wait,让连接在返回后立马关闭,成为一个可用连接。新增选项:

<Connectorport=“11011” protocol=“org.apache.coyote.http11.Http11NioProtocol” connectionTimeout=“20000” maxThreads=“1000” URIEncoding=“UTF-8” keepAliveTimeout=“0” />

其中的keepAliveTimeout="0"是解决这个问题的关键。这个参数在其中一个应用进行试验,原本经常有CLOSE_WAIT,新增之后,基本没有,而且也没有报错。

在这里插入图片描述

总结

通过实际的现场场景,展示了整个排查的过程,中间涉及jmapjstackjstatarthasjprofiler等命令及软件。熟练地使用这些命令,可以得到很多有用的信息,并加以解决。

在这里插入图片描述

参考链接

jmap官方说明文档
jstack官方说明文档
jstat官方说明文档
arthas官方文档

参考图

JVM结构

在这里插入图片描述

TCP的三次握手和四次挥手

在这里插入图片描述

随缘求赞

如果我的文章对大家产生了帮忙,可以在文章底部点个赞或者收藏;
如果有好的讨论,可以留言;
如果想继续查看我以后的文章,可以点击关注
可以扫描以下二维码,关注我的公众号:枫夜之求索阁,查看我最新的分享!

在这里插入图片描述

拜拜

这篇关于问题解决:遇到tomcat的假死问题,如何排查问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114813

相关文章

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

element-ui下拉输入框+resetFields无法回显的问题解决

《element-ui下拉输入框+resetFields无法回显的问题解决》本文主要介绍了在使用ElementUI的下拉输入框时,点击重置按钮后输入框无法回显数据的问题,具有一定的参考价值,感兴趣的... 目录描述原因问题重现解决方案方法一方法二总结描述第一次进入页面,不做任何操作,点击重置按钮,再进行下

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

Apache Tomcat服务器版本号隐藏的几种方法

《ApacheTomcat服务器版本号隐藏的几种方法》本文主要介绍了ApacheTomcat服务器版本号隐藏的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1. 隐藏HTTP响应头中的Server信息编辑 server.XML 文件2. 修China编程改错误

解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题

《解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题》本文主要讲述了在使用MyBatis和MyBatis-Plus时遇到的绑定异常... 目录myBATis-plus-boot-starpythonter与mybatis-spring-b

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

mysql主从及遇到的问题解决

《mysql主从及遇到的问题解决》本文详细介绍了如何使用Docker配置MySQL主从复制,首先创建了两个文件夹并分别配置了`my.cnf`文件,通过执行脚本启动容器并配置好主从关系,文中还提到了一些... 目录mysql主从及遇到问题解决遇到的问题说明总结mysql主从及遇到问题解决1.基于mysql

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11