生产环境OOM\死锁问题排查修复
OOM:
1.快速恢复业务:如果是集群中的一台机器故障,先隔离故障服务器;如果是多台,则根据Nginx转发策略,对该功能转发到单独的集群,与其他流量隔离,确保其他业务不受影响
2.收集内存溢出Dump文件:方式有两种:
1.设置JVM启动参数
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/jvmdump
设置之后,在每次发生内存溢出时,JVM会自动将堆转储,dump文件存放在-XX:HeapDumpPath指定的路径下
2.使用jmap命令收集
通过jamp -dump:live,format=b,file=/opt/jvm/dump.hprof pid
3.分析dump文件:可以通过MAT(Memory Analyzer Tool)进行分析,使用MAT打开Dump文件后,首页截图如下:

工具按钮介绍:
:直方图视图,将堆中所有的内存消耗情况统计出来,其如图所示:

:内存使用树状结构,以线程为维度,树状形式展开,如图所示:

线程栈,其截图如下:


根据该图,可以明确,堆的总大小为1.9G,被4个线程全部占据,导致其他线程无法再申请资源,抛出堆内存溢出错误。
接下来,我通常的做法是直接去看
这个视图(以线程为基本维度,查找线程中占用内存的对象),为后续定位排查提供必要的依据。


从上面的截图中可以得出如下关键信息点:
org.apache.ibatis.executor.result.DefaultResultHandler内部持有一个List,其原始为java.util.HashMap,从这个类基本可以看出是与数据库的查询相关,对数据库返回结果的解码并组织成HashMap。
这个List中的元素总共有146033个,初步可以判断出是在一次查询中从数据库中一次查询出了太多数据,造成了内存溢出。
由于SQL查询代码中,是用HashMap来接收数据库中的返回字段,无法一时间看出是那个查询,那我们能不能精确找到是哪一个查询,哪一行代码,甚至与哪一条SQL语句呢?
答案是可以的,我们可以从
视图一探究竟。
温馨提示:
视图使用技巧:展开技巧:沿着使用率最高的项一层一层进行展开,直至发现具体占用内存的对象。
接下来我们从 视图去寻找是哪个方法,哪条SQL语句触发的。
具体方法:首先完全展开一个线程,从展开图的底部向上寻找:
其线程的入口(控制层代码)

继续往上查找,要找到SQL语句,应该找到Mybatis处理结果集相关的类,如图所示:

然后展开boundSql即能找到SQL语句:

然后鼠标可以放在SQL属性中,右键,可以将SQL语句复制出来。

由于这里涉及到公司的代码机密,故在这里不贴出具体的SQL语句。
这里根据后面的分析,原来是在做导出功能的时候,没有使用分页对数据进行分页查询,分页写入Excel文件,而是一次将全部数据查询,导致导出功能如果并发数超过4个时,就会将所有内存耗尽。
解决方案:
首先在运维层面将该请求导入到指定的一台服务器上,是导出任务与其他任务进行隔离,避免对其他重要服务造成影响。
项目组对其代码进行修复,可以使用分页查数据,然后分配写入Excel。
死锁:
1.查看系统日志,找到对应的死锁方法:
org.springframework.dao.CannotAcquireLockException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.LockAcquisitionException: could not execute statement
at com.kuding.order.services.ChildOrderService.lambda$modifyChildOrderDeliverStatus$23(ChildOrderService.java:423)
at com.kuding.order.services.ChildOrderService.modifyChildOrderDeliverStatus(ChildOrderService.java:416)
at com.kuding.order.controllers.ChildOrderController.modifyDeliveringStatus(ChildOrderController.java:68)
at com.kuding.common.basestructure.filters.GeetestFilter.doFilter(GeetestFilter.java:102)
Caused by: org.hibernate.exception.LockAcquisitionException: could not execute statement
at com.kuding.common.basestructure.interfaces.daointerfacesv2.AbstractDao.create(AbstractDao.java:22)
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
2.在mysql中使用命令:SHOW ENGINE INNODB STATUS;总能获取到最近一些问题信息,通过搜索deadlock 关键字即可找到死锁的相关日志信息。
分析哪些语句申请锁资源冲突,结合1来确定对应的代码,通过使用分布式锁或者修改获取数据锁顺序来修复
生产环境OOM\死锁问题排查修复的更多相关文章
- 总结:利用asp.net core日志进行生产环境下的错误排查(asp.net core version 2.2,用IIS做服务器)
概述 调试asp.net core程序时,在输出窗口中,在输出来源选择“调试”或“xxx-ASP.NET Core Web服务器”时,可以看到类似“info:Microsoft.AspNetCore. ...
- 生产环境JAVA进程高CPU占用故障排查
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- 生产环境下JAVA进程高CPU占用故障排查
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- 使用Windbg找出死锁,解决生产环境中运行的软件不响应请求的问题
前言 本文介绍本人的一次使用Windbg分析dump文件找出死锁的过程,并重点介绍如何确定线程所等待的锁及判断是否出现了死锁. 对于如何安装及设置Windbg请参考:<使用Windbg和SoS扩 ...
- 生产环境下JAVA进程高CPU占用故障排查---temp
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- 生产环境部署springcloud微服务启动慢的问题排查
今天带来一个真实案例,虽然不是什么故障,但是希望对大家有所帮助. 一.问题现象: 生产环境部署springcloud应用,服务部署之后,有时候需要10几分钟才能启动成功,在开发测试环境则没有这个问题. ...
- 生产出现oom问题,怎么排查?
生产出现oom问题,怎么排查? 1.使用dmesg命令查看系统日志 dmesg |grep -E 'kill|oom|out of memory',可以查看操作系统启动后的系统日志,这里就是查看跟 ...
- 生产环境中,数据库升级维护的最佳解决方案flyway
官网:https://flywaydb.org/ 转载:http://casheen.iteye.com/blog/1749916 1. 引言 想到要管理数据库的版本,是在实际产品中遇到问题后想到的 ...
- mysql innodb引擎 一次线上死锁分析排查步骤
我们的线上erp系统一天使用人员反映部分数据死活保存不上而且页面操作很慢.开始以为操作数据量大的原因, 后来查看了我们线上的glowroot系统,发现slowtrace中有超长时间的访问,点开查看详情 ...
随机推荐
- 【LG5444】[APIO2019]奇怪装置
[LG5444][APIO2019]奇怪装置 题面 洛谷 题目大意: 给定\(A,B\),对于\(\forall t\in \mathbb N\),有二元组\((x,y)=((t+\lfloor\fr ...
- JS 数组,对象常用方法 集合
数组 1.数组去重: 主要是使用的 new Set() 方法 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Referen ...
- Leetcode 5281. 使结果不超过阈值的最小除数
又一次参赛,除了第一道Easy题和第二道Medium外,剩下的两道在有限时间内,要么没思路,要么思路不对,超时,要么有思路调试出错,还需多加练习! (这次的第三题,在循环从1开始,直到找到满足地为止, ...
- Kubeadm部署安装kubernetes1.12.1
1.环境准备(这里是master) CentOS 7.6 两台配置如下,自己更改主机名,加入hosts, master和node 名字不能一样 # hostname master # hostname ...
- MySQL5.7调优参数
1. 更改MySQL Data File位置 datadir=/data/mysqlsocket=/data/mysql/mysql.sock 2. 调整OS参数 * soft nproc 10240 ...
- gcc O2优化选项对内嵌汇编以及函数递归调用的影响
学习和使用c这些年来,很多方面都未深入研究过,就如脱离了IDE后,我可能连编译一个c文件的命令都写不出来. 最近需要在c中内嵌汇编解决问题,参考网上相关的资料写了一段汇编代码,在测试的时候时好时坏,找 ...
- .net core mvc中input保留多位小数
本篇介绍:如何在mvc中使用html标签保留多位小数 你需要知道: @html标签的使用: https://blog.csdn.net/pasic/article/details/7093802 js ...
- kali 添加swap 交换分区
这里采用的是添加交换文件 mkdir /swap #创建/swap 文件夹 dd if=/dev/zero of=/swap/swapfile bs=1M count=4096 # 在/swap 下创 ...
- POJ-数据结构-优先队列模板
优先队列模板 优先队列是用堆实现的,所以优先队列中的push().pop()操作的时间复杂度都是O(nlogn). 优先队列的初始化需要三个参数,元素类型.容器类型.比较算子. 需要熟悉的优先队列操作 ...
- php 跳出循环 break
break语句可以带一个参数n,表示跳出循环的层数,如果要跳出多重循环的话,可以用n来表示跳出的层数,如果不带参数默认是跳出本重循环.
视图使用技巧:展开技巧:沿着使用率最高的项一层一层进行展开,直至发现具体占用内存的对象。