问题解决系列:遇到tomcat的假死问题,如何排查问题(代码片段)

author author     2022-12-09     434

关键词:

(文章目录)

问题场景

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

问题环境

软件 版本
tomcat 7.0
JDK 1.6
Centos 6

问题原因

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 = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 3221225472 (3072.0MB)
   NewSize          = 2686976 (2.5625MB)
   MaxNewSize       = -65536 (-0.0625MB)
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 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 Generation
   capacity = 2147483648 (2048.0MB)
   used     = 2142115640 (2042.8806686401367MB)
   free     = 5368008 (5.119331359863281MB)
   99.75003264844418% used
PS Perm Generation
   capacity = 161087488 (153.625MB)
   used     = 159574696 (152.18228912353516MB)
   free     = 1512792 (1.4427108764648438MB)
   99.06088795673566% used

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

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

jstat  -gcutil pid 250 7

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

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

S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 82.15 84.94 99.84 50388 5413.400 2870 18355.985 23769.385
0.00 0.00 86.08 84.94 99.84 50388 5413.400 2870 18355.985 23769.385
0.00 0.00 90.86 84.94 99.84 50388 5413.400 2870 18355.985 23769.385
0.00 0.00 93.88 84.94 99.84 50388 5413.400 2870 18355.985 23769.385
0.00 0.00 97.54 84.94 99.84 50388 5413.400 2870 18355.985 23769.385
23.60 0.00 5.96 84.94 99.84 50389 5413.476 2870 18355.985 23769.461
23.60 0.00 21.19 84.94 99.84 50389 5413.476 2870 18355.985 23769.461
说明
S0 Heap上的 Survivor space 0 段已使用空间的百分比
S1 Heap上的 Survivor space 1 段已使用空间的百分比
E Heap上的 Eden space 段已使用空间的百分比
O Heap上的 Old space 段已使用空间的百分比
P Perm space 已使用空间的百分比
YGC 从程序启动到采样时发生Young GC的次数
YGCT Young 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,让连接在返回后立马关闭,成为一个可用连接。新增选项:

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

总结

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

参考链接

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

参考图

JVM结构

TCP的三次握手和四次挥手

随缘求赞

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

如何解决直播过程中的直播功耗高问题|直播疑难杂症排查

...推出了这个新的系列《直播疑难杂症排查》,把解决直播问题的经验逐步分享出来,同时也会穿插一些音视频开发的基础知识和优化经验,希望能够帮助到直播领域的开发者们。 本系列会涵盖的内容包括但不限于如下一些主... 查看详情

大数据问题排查系列-hive踩坑记

...言大家好,我是明哥!本片博文是“大数据线上问题排查系列”大类别之一,讲述前段时间我司某产品在某券商遇到的一个问题及解决方案,其背后涉及到hive的一个BUG,在hive3.0才修复。以下是正文。问题现象cdh6.2.... 查看详情

jvm线上故障排查基本操作(转)

...  对于后端程序员,特别是Java程序员来讲,排查线上问题是不可避免的。各种CPU飚高,内存溢出,频繁GC等等,这些都是令人头疼的问题。楼主同样也遇到过这些问题,那么,遇到这些问题该如何解决呢?  首先,出现问题... 查看详情

大数据线上问题排查系列-hive踩坑记(代码片段)

大数据线上问题排查系列-HIVE踩坑记前言大家好,我是明哥!本片博文是“大数据线上问题排查系列”大类别之一,讲述前段时间我司某产品在某券商遇到的一个问题及解决方案,其背后涉及到hive的一个BUG,在hive3.... 查看详情

整理性能分析篇

...-基础理论篇Linux性能分析——上下文切换服务器负载过高问题分析如何评估服务器的单机处理能力服务器性能评估服务器性能估算服务器处理能力,你估算正确过吗关于JavaTomcat内存溢出排查一个Java对象到底占用多大内存Tomcat假... 查看详情

大数据问题排查系列-hdfsfilesystemapi的正确打开方式,你get了吗?(代码片段)

大数据问题排查系列-HDFSFileSystemAPI的正确打开方式,你GET了吗?前言大家好,我是明哥!本片博文是“大数据问题排查系列”之一,我们首先会聊聊一个问题的现象原因和解决方法,然后给出HDFSFileSystemAPI... 查看详情

jvm线上故障排查基本操作

#前言对于后端程序员,特别是Java程序员来讲,排查线上问题是不可避免的。各种CPU飚高,内存溢出,频繁GC等等,这些都是令人头疼的问题。楼主同样也遇到过这些问题,那么,遇到这些问题该如何解决呢?首先,出现问题,... 查看详情

系列序—直播疑难杂症排查

...七牛做直播SDK一年多了,帮助客户解决过各种形形色色的问题,如直播卡顿、马赛克、花屏、黑屏、杂音、音画不同步等等等等,这其中,有一些是网络原因,有一些是客户的使用姿势问题,有一些是参数配置错误,当然,也有... 查看详情

一叶障目:排查问题的思路

...忙碌,遇到了两次莫名不知如何解决的错误,由此暴露的问题让人不禁反思: 好的分析排查习惯比问题本身更值得关注。 首先是前天晚上遇到的一个问题是这样的:我需要定时去从redis的zset里面取得一些key,然后查询数... 查看详情

解决在googlecloud中安装anaconda时遇到的系列问题

参考技术A本文主要解决在GoogleCloud上通过SSH安装Anaconda时遇到的一系列问题,具体配置VMinstance,VPCnetwork,Firewallrules等的详细教程请参见:HowtoSetupanInstancetoRunaJupyterNotebookinGCP?。 查看详情

jenkins-安装jenkins过程中遇到问题的排查思路(代码片段)

...y/category/1645399.html 安装Jenkins过程中,可能会遇到一些问题,我们要如何排查呢? 第一步:能联网?通过ping命令看能不能联网pingwww.baidu.com 第二步:看进程是否存在ps-ef|grepjenkins   第三步:看对应端口是否有... 查看详情

滴滴一面:bigkey问题很致命,如何排查和处理?(代码片段)

...网盘资源大合集价值>10000元加尼恩领取滴滴一面:BigKey问题很致命,如何排查和处理?说在前面在40岁老架构师尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如极兔、有赞、希音、百度、网易、滴滴的面试资... 查看详情

如何打日志才能方便排查问题?

...lovesqcc/...在程序中打错误日志的主要目标是为更好地排查问题和解决问题提供重要线索和指导。但是在实际中打的错误日志内容和格式变化多样,错误提示上可能残缺不全、没有相关背景、不明其义,使得排查解决问题成为非常... 查看详情

答学员问网站换ip后遇到的问题排查思路(代码片段)

文章目录遇到问题先进行基本的问题排查1.查看IP2.是否能通网3.关闭防火墙和selinux4.使用windows的浏览器访问问题复现1.安装好wordpress,确保能够访问2.修改IP,进行测试3.访问测试:问题排查问题解决方案遇到问题学员... 查看详情

答学员问网站换ip后遇到的问题排查思路(代码片段)

文章目录遇到问题先进行基本的问题排查1.查看IP2.是否能通网3.关闭防火墙和selinux4.使用windows的浏览器访问问题复现1.安装好wordpress,确保能够访问2.修改IP,进行测试3.访问测试:问题排查问题解决方案遇到问题学员... 查看详情

flink实战系列flink提交任务遇到serverresponseinternalservererror怎么排查(代码片段)

...细的报错信息,只看这个Internalservererror是看不出来任何问题的,JM里有关的报错信息如下:2022-03-2718:29:51,026ERRORorg.apache.flink.runtime.webmonitor.handlers.JarR 查看详情

elasticsearch常见错误及如何排查错误(代码片段)

目录1可能遇到的问题2UnknownkeyforaSTART_OBJECTin[XXXX].3TermQuery精确查询失效问题解决3.1问题3.2解决办法3.3原因4Elasticsearch解决只能查询10000条数据方案1可能遇到的问题一般我的习惯是先写javaAPI再去拿着代码中Debug数据进行排错,有... 查看详情

eclipse配置tomcat遇到的问题以及解决办法

...好的工具,而笔者在配置Tomcat服务器的时候遇到了一些小问题,在这里给大家总结一些经验,希望能帮助同样遇到这些问题的广大同行们能够简单轻松地解决这些问题~  笔者在以前自学JSP的时候曾经用过Tomcat+Eclipse,并且已经... 查看详情