糟了,线上服务出现OOM了

news2025/7/20 5:59:40

前言

前一段时间,公司同事的一个线上服务OOM的问题,我觉得挺有意思的,在这里跟大家一起分享一下。

我当时其实也参与了一部分问题的定位。

1 案发现场

他们有个mq消费者服务,在某一天下午,出现OOM了,导致服务直接挂掉。

当时我们收到了很多内存的报警邮件。

发现问题之后,运维第一时间,帮他们dump了当时的内存快照,以便于开发人员好定位问题。

之后,运维重启了该服务,系统暂时恢复了正常。

大家都知道,如果出现了线上OOM问题,为了不影响用户的正常使用,最快的解决办法就是重启服务。

但重启服务治标不治本,只能临时解决一下问题,如果不找到真正的原因,难免下次在某个不经意的时间点,又会出现OOM问题。

所以,有必要定位一下具体原因。

2 初步定位问题

当时运维dump下来的内存快照文件有3G多,太大了,由于公司内网限制,没办法及时给到开发这边。

没办法,只能先从日志文件下手了。

在查日志之前,我们先查看了prometheus上的服务监控。查到了当时那个mq消费者服务的内存使用情况,该服务的内存使用率一直都比较平稳,从2022-09-26 14:16:29开始,出现了一个明显的内存飙升情况。

根据以往经验总结出来的,在追查日志时,时间点是一个非常重要的过滤条件。

所以,我们当时重点排查了2022-09-26 14:16:29前后5秒钟的日志。

由于这个服务,并发量不大,在那段时间的日志量并不多。

所以,我们很快就锁定了excel文件导入导出功能。

该功能的流程图如下:25001eec3b543358968c123a58fa8611.png

  1. 用户通过浏览器上传excel,调用文件上传接口。

  2. 该接口会上传excel到文件服务器。然后将文件url,通过mq消息,发送到mq服务器。

  3. mq消费者消费mq消息,从文件服务器中获取excel数据,做业务处理,然后把结果写入新的excel中。

  4. mq消费者将新excel文件上传到文件服务器,然后发websocket消息通知用户。

  5. 用户收到通知结果,然后可以下载新的excel。

经过日志分析,时间点刚好吻合,从excel文件导入之后,mq消费者服务的内存使用率一下子飙升。

3. 打不开dump文件

从上面分析我们得出初步的结论,线上mq消费者服务的OOM问题,是由于excel导入导出导致的。

于是,我们查看了相关excel文件导入导出代码,并没有发现明显的异常。

为了找到根本原因,我们不得不把内存快照解析出来。

此时,运维把内存快照已经想办法发给了相关的开发人员(我的同事)。

那位同事用电脑上安装的内存分析工具:MAT(Memory Analyzer Tool),准备打开那个内存快照文件。但由于该文件太大,占了3G多的内存,直接打开失败了。

1ec3aeace52c4db66cf7558259d5e356.png

MemoryAnalyzer.ini文件默认支持打开的内存文件是1G,后来它将参数-xmx修改为4096m。

修改之后,文件可以打开了,但打开的内容却有问题。

猛然发现,原来是JDK版本不匹配导致的。

他用的MAT工具是基于SunJDK,而我们生成环境用的OpenJDK,二者有些差异。

SunJDK采用JRL协议发布,而OpenJDK则采用GPL V2协议发布。两个协议虽然都是开放源代码的,但是在使用上的不同,GPL V2允许在商业上使用,而JRL只允许个人研究使用。

所以需要下载一个基于OpenJDK版本的MAT内存分析工具。

4. 进一步分析

刚好,另一个同事的电脑上下载过OpenJDK版本的MAT内存分析工具。把文件发给他帮忙分析了一下。402b17aecd48b11b723b97ec35945e0e.png

最后发现org.apache.poi.xssf.usermodel.XSSFSheet类的对象占用的内存是最多的。

0ba0c6b57bac3f09e95febc0fe139ffa.png

目前excel的导入导出功能,大部分是基于apache的POI技术,而POI给我们提供了WorkBook接口。常用的WorkBook接口实现有三种:

  • HSSFWorkbook:它是早期使用最多的工具,支持Excel2003以前的版本,Excel的扩展名是.xls。只能导出65535条数据,如果超过最大记录条数会报错,但不会出现内存溢出。

  • XSSFWorkbook:它可以操作Excel2003-Excel2007之间的版本,Excel的扩展名是.xlsx。最多可以导出104w条数据,会创建大量的对象存放到内存中,可能会导致内存溢出。

  • SXSSFWorkbook:它可以操作Excel2007之后的所有版本,Excel的扩展名是.xlsx。SXSSFWorkbook是streaming版本的XSSFWorkbook,它只会保存最新的rows在内存里供查看,以前的rows都会被写入到硬盘里。用磁盘空间换内存空间,不会导致内存溢出。

看到了这个类,可以验证之前我们通过日志分析问题,得出excel导入导出功能引起OOM的结论,是正确的。那个引起OOM问题的功能,刚好使用了XSSFWorkbook处理excel,一次性创建了大量的对象。关键代码如下:

XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));

我们通过MAT内存分析工具,已经确定OOM问题的原因了。接下来,最关键的一点是:如何解决这个问题呢?

5. 如何解决问题?

根据我们上面的分析,既然XSSFWorkbook在导入导出大excel文件时,会导致内存溢出。那么,我们改成SXSSFWorkbook不就行了?关键代码改动如下:

XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));

使用SXSSFWorkbook将XSSFWorkbook封装了一层,其中100表示excel一次读入内存的最大记录条数,excel中其余的数据将会生成临时文件保存到磁盘上。这个参数,可以根据实际需要调整。还有一点非常重要:

sheet.flushRows();

需要在程序的结尾处加上上面的这段代码,不然生成的临时文件是空的。这样调整之后,问题被暂时解决了。

此外,顺便说一句,在使用WorkBook接口的相关实现类时,用完之后,要记得调用close方法及时关闭喔,不然也可能会出现OOM问题。

6. 后续思考

其实,当时我建议过使用阿里开源的EasyExcel解决OOM的问题。但同事说,excel中有很多样式,在导出的新excel中要保留之前的样式,同时增加一列,返回导入的结果。

如果使用EasyExcel不太好处理,使用原始的Workbook更好处理一些。

但是使用mq异步导入excel文件这套方案,如果并发量大的话,任然可能会出现OOM问题,有安全隐患。因此,有必要调整一下mq消费者。

后来,mq消费者的线程池,设置成4个线程消费,避免消费者同时处理过多的消息,读取大量的excel,导致内存占用过多的问题。当然线程个数参数,可以根据实际情况调整。

此外,使用阿里的arthas也可以定位线上OOM问题,后面会有专门的文章介绍,感兴趣的小伙伴可以关注一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker技术简介

目录 概念 命令 数据卷 DockerFile 应用部署 服务编排 私有仓库 概念 Docker 是一个开源的应用容器引擎,而容器技术是一种轻量级虚拟化方案(虚拟机太繁重了不够轻量级),Docker的基础是Linux容器(LXC&#xff09…

离线安装ceph集群(ceph-13.2.10)

记录:332 场景:在CentOS 7.9操作系统上,使用ceph的rpm-mimic的ceph-13.2.10安装ceph集群。应用ceph对象存储(ceph object store);应用ceph块设备(ceph block device);应用ceph文件系统(ceph file system)。 版本&…

数据结构(5)树形结构——二叉搜索树(JAVA代码实现)

5.1.概述 二叉搜索树,也叫二叉查找树、二叉排序树,顾名思义,这种二叉树是专门用来进行数据查找的二叉树。二叉搜索树的查找其实就是二分查找。 二叉搜索树的定义: 二叉搜索树可以为空如果二叉搜索树不为空,那么每个…

Design Compiler工具学习笔记(7)

目录 引言 背景知识 多时钟设计 DC 输出文件分析 实际操作 设计源码 综合脚本 综合网表 SDF文件 SDC文件 REPORT文件 引言 本篇继续学习 DC的基本使用。本篇主要学习 DC 综合之后的效果分析,多同步时钟设计以及 DC 综合完成之后的各种输出文件。 前文链…

微信小程序开发基础(03视图与逻辑)

学习目标 能够知道如何实现页面之间的导航跳转 能够知道如何实现下拉刷新效果 能够知道如何实现上拉加载更多效果 能够知道小程序中常用的生命周期函数 页面导航 1. 什么是页面导航 页面导航指的是页面之间的相互跳转。例如,浏览器中实现页面导航的方式有如下两…

关于环境保护html网页设计完整版,5个以环境为主题的网页设计与实现

🎀 精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

《剑指 Offer 》—50. 第一个只出现一次的字符

《剑指 Offer 》—50. 第一个只出现一次的字符 一、题目内容 原题连接:https://leetcode.cn/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/description/ 题目:在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。…

【专栏】核心篇06| Redis 存储高可用背后的模式

关注公众号 【离心计划】呀,一起逃离地球表面 Redis专栏合集 【专栏】01| Redis夜的第一章 【专栏】基础篇02| Redis 旁路缓存的价值 【专栏】基础篇03| Redis 花样的数据结构 【专栏】基础篇04| Redis 该怎么保证数据不丢失(上) 【专栏…

RabbitMQ------发布确认高级(消息回调、回退、备份交换机)(八)

RabbitMQ------发布确认高级(八) 可能由于某些意外情况,导致RabbitMQ重启,在RabbitMQ重启过程中,生产者投递消息失败,导致消息丢失。 如果才能够保证RabbitMQ的消息可靠性呢? 可能出现两种问题…

大数据毕设选题 - 深度学习火焰识别检测系统(python YOLO)

文章目录0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数:3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层5 数据集准备5.1 数据标…

CSRF漏洞简介

今天继续给大家介绍渗透测试相关知识,本文主要内容是CSRF漏洞原理、产生与危害。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负! 再次强调:严禁对未…

Maven——分模块开发与设计(重点)

目录 一、模块拆分 1.1 模块拆分思想 1.2 pojo模块拆分 1.3 dao模块拆分 1.4 service模块拆分 1.5 controller模块拆分 二、 聚合——模块聚合 三、继承——模块继承 一、模块拆分 1.1 模块拆分思想 左侧:我们从前的架构,一个人独立做的所有工作文件…

shell脚本的条件判断1:字符串和数字和比较

前言 写脚本时,为了让脚本更接近人类思考问题的方式,可以对各种情况进行判断。例如,经常需要判断某些条件是否成立,如果条件成立该如何处理,如果条件不成立又该如何处理,这些都可以通过Shell脚本的if语句结…

大数据_什么是数据中台?

目录 一、数据中台的定义 二、数据中台必备的是个核心能力 三、数据中台VS业务中台 四、数据中台VS数据仓库 五、数据中台VS现有信息架构 六、数据中台的业务价值与技术价值 一、数据中台的定义 数据中台是一套可持续“让企业的数据用起来”的机制,是一种战略…

vm的生命周期钩子

vm的生命周期钩子(共11个): 前8个: 将要创建>调用beforeCreate函数 创建完毕>调用created函数 将要挂载>调用beforeMount函数 (重要)挂载完毕>调用mounted函数>【重要钩子】 将要更新…

用户画像洞察分类模型 - 前端页面展示

文章目录一、前端与数据智能二、 体验优化需求场景跳失预测交互偏好智能 UI三、 关键技术鲸幂 UICook(智能UI)DataCookPipCookPipeline四、 体验优化实践数据智能实践的一般流程数据采集数据分析 -如何对数据进行分析处理并得出结论数据应用 - 分析结论如…

【C++】string类接口的了解和使用

为什么我们要学string类呢?那是必须是为了方便啊!在C语言中,我们创建一个字符串,有很多操作或者必须要注意的细节会把控不住,所以C中出现了string类,让我们应对字符串等oj题也方便快捷了许多! 目…

linux搭建redis数据库实现远程c语言访问

文章目录 linux安装reidis数据库c语言使用hiredis库实现redis数据库的操作测试代码使用hiredis库制作一个redis数据库管理系统linux安装reidis数据库 linux安装reidis数据库 sudo apt-get install redis-server使用systemctl命令查看redis服务运行状态 sudo systemctl statu…

Visual C++ 2010开发的程序在其它电脑上运行提示“找不到MSVCR100D.dll”原因及解决

Visual C 2010开发的程序在其它电脑上运行提示“找不到MSVCR100D.dll”原因及解决 Microsoft Visual C(简称Visual C、MSVC、VS或VC)2010是微软公司的免费C开发工具,具有集成开发环境,可提供编辑C语言,C以及C/CLI等编程…

惊喜:2023前瞻版Java面试指南,不止八股文

前言: 2022年马上就要过去了,即将要到来的就是2023年的金三银四面试季,随着政策的放宽,经济的逐步复苏,岗位的需求也会越来越大,所以趁这段时间进行知识储备将会是最好的时间段,永远要做快人一…