当前位置: 首页 > news >正文

close wait 过多原因_springboot tomcat 挂掉,假死无响应原因总结和解决方案

tomcat假死原因

以前遇到tomcat莫名奇妙的假死了,没有任何的响应,然后重启后又可以了,隔段时间又假死了。以前不懂的处理和排除原因,纠结的半死。无从入手,都想砸电脑,小伙伴们有遇到过,我遇到过4次。

其实tomcat假死引起的原因有很多,要具体分析一下和排查一下。

tomcat假死有以下几种可能的原因:

  • redis的连接池资源没释放掉(tcp没释放掉,tcp状态为close_wait)
  • 数据库连接池资源没释放掉(tcp没释放掉,tcp状态为close_wait)
  • 上传文件资源没关闭掉 (tcp没释放掉,tcp状态为close_wait)
  • httpclient请求没关闭掉 (tcp没释放掉,tcp状态为close_wait)
  • 线程死锁
  • 线程被阻塞了,没继续往下执行

tomcat的假死的原因有很多,很多是由于tcp没有释放掉。具体怎么排查原因,下面会介绍一下。

案例1

顺便说我遇到的一个坑,我曾经部署专门做定时任务项目,这个是用spring的quartz做的。发现定时任务执行一段时间后,居然没响应了,tomcat没挂掉,cpu和内存也正常。就是定时任务不执行。查看了线程,也没有死锁。后面查了很久,居然quartz的定时任务调度居然开启的是单线程的。由于我其中一个定时任务要执行消息写入数据库,这个量非常大,而且服务器配置比较差,写入比较慢。所以导致这个任务要执行差不多1天,导致其他定时任务不执行,所以还以为tomcat挂掉了。所以有时候要排查线程数是否足够。

案例2

当服务器挂掉的时候,查看一下日志看能不能查出问题。日志查看不出来的时候,查看运行时候cpu和内存的波动,如果cpu和内存波动很大,就去查看堆栈信息,看哪个线程占用的cpu和内存比较高。dump线程信息,查看一下具体代码哪个位置引起的。

查看堆栈信息可以使用以下工具

  • jdk自带的console.exe (window)
  • jdk自带的jvisualvm.exe (window)
  • jstack(linux)
  • alibaba/arthas 阿里巴巴的插件,挺好用的,推荐使用,还可以反编译源码

首先查看cpu和内存

用jvisualvm(也可以远程连接到linux上面,改天我写个文章)

49988e267f9b46c95d86734f7dc1cf76.png

如果是linux系统的话,可以用top -c 查看cpu和内存

top -c
54a1afa02561606a01e8a5abab5b4b14.png

查看线程信息

linux

jstack java的进程id
ca3746738419b881f276e6d7156b42a4.png

如果要查看有没有线程死锁,你可以按照下面命令做

jstack java的进程id >1.txt

然后在1.txt文件查找一下有没有DeadThread关键词。没有就是没死锁

jconsole比较简单

7e2214e6f431d57f7cf70ce0849db2a7.png

当cpu和内存剧增的时候,可以查看是哪几个线程引起的,定位到这个线程。查看线程名称,基本上可以定位到问题。

top c

可看出PID为7149的java进程占用cpu最高,达到了98%

b25ddbc6f659e90305c3ba77483dce60.png

查看进程中最耗cpu的子线程

top -p 7149 -H

如下图:可看出PID为7166的线程占用cpu最高,达到了97.7%

44b4faf18058c3fde74584d511a5a0eb.png

将最耗cpu的线程id转换为16进制输出

 printf "%x " 7166
475589318d68fac7830cc8b474865a32.png

查询具体出现问题的代码位置

jstack 7149 | grep 1bfe -A 30

如下图:可看出是JVMLearnApplication类的第18行出现问题

54575703ac2e4097ca47a4a388f27993.png

我曾经遇到过一个坑,就是activemq的广播消息太多,然后程序用线程池消费,线程池线程数配置太小,消费速度跟不上,就会堆到线程池队列中排队,内存剧增,cpu最后也跟这剧增。导致tomcat挂掉。最后把线程池的线程数配置大点,后面就正常了。

案例3

当cpu和内存正常的时候,线程也没有死锁,tomcat也没有死掉,就是访问不了,全部访问状态502超时。这个是怎么回事呢。别急,下面介绍怎么解决。

当出现这种情况的时候,先去查一下tcp连接情况,

Docker容器中安装netstat命令,如果没有netstat命令

apt-get updateapt-get install net-tools

linux查看方式如下:

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

如果出现大量的close_wait的状态。那表示tcp没有正确释放。

定位到是tcp问题了,那接下来怎么办呢

http请求进来,都是502超时响应,那就表示处理http请求的线程都阻塞了,查看具体哪行代码阻塞就行了。

查找线程http-nio-28001-exec这个些线程的线程信息,dump下来,看具体是请求什么阻塞了。

6df20cb01f5c8ec19cff1aae164e8946.png

如果是请求redis线程池资源阻塞了,那看一下redis资源为什么没释放,或者什么不够用了。查看一下最近代码都对redis进行什么操作。

数据库和上传文件和httpclient请求没关闭掉 都是跟redis一样的道理。

我之前遇到的坑就是redis引起的。我一个同事用redisTemplate.getConnect()的到一个管道连接,然后在连接里面有for循环调用redisTempate.get()方法,这样导致了redis连接池不够用。管道没释放。然后http请求都是用经过权限校验的,是shiro+redis做的。所有请求经过redis的时候就阻塞了。所有tomcat假死了。

总之tomcat假死大概就这些原因,还有需要注意点,有写批量操作,最好都用同个管道,不要每个都请求一个资源,这样会导致资源不够用,tcp都是close_wait状态。

改天介绍一下alibaba/arthas的这个插件怎么使用,真的非常方便

相关文章:

  • python tkinter_tkinter转盘抽奖代码、调整和逐步优化的python分析
  • path manipulation怎么解决_TensorFlow Object Detection API遇到的问题及解决
  • python安装后怎样配解释器_pycharm 安装后如何设置与更换解释器
  • cloud压缩怎么彻底删除_怎么彻底删除mysql服务?
  • 西门子et200 分布式i/o_你真的了解西门子Profinet吗?从RT切换到IRT出问题
  • python简述题_python考核试题及答案
  • python 项目示例_Python project.Project方法代码示例
  • python12_python12_异常处理
  • python从date目录导入数据集_python – 将数据集转换为HDF5数据集
  • python join_Python中的join()函数的用法
  • python文字识别算法_使用Python检测文章抄袭及去重算法原理解析
  • python代码图片头像_Python图片裁剪实例代码(如头像裁剪)
  • python视频转换字符动画_视频转字符动画
  • python的requests模块功能_Python中requests模块的核心使用(上)
  • python分块处理功能_在python3下对数据分块(8x8大小)使用OpenCV的离散余弦变换DCT
  • $translatePartialLoader加载失败及解决方式
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • es6
  • mac修复ab及siege安装
  • NSTimer学习笔记
  • Promise初体验
  • 和 || 运算
  • 排序算法之--选择排序
  • 前端
  • 前端性能优化--懒加载和预加载
  • 实现菜单下拉伸展折叠效果demo
  • 智能合约开发环境搭建及Hello World合约
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​ubuntu下安装kvm虚拟机
  • ​虚拟化系列介绍(十)
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (第二周)效能测试
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)ssm失物招领系统 毕业设计 182317
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .Net Redis的秒杀Dome和异步执行
  • .NET 表达式计算:Expression Evaluator
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .net 受管制代码
  • .net生成的类,跨工程调用显示注释
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • @Transactional类内部访问失效原因详解
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [ 数据结构 - C++]红黑树RBTree
  • [ 转载 ] SharePoint 资料
  • []常用AT命令解释()
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [20140403]查询是否产生日志
  • [3D基础]理解计算机3D图形学中的坐标系变换
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [Android 数据通信] android cmwap接入点