千锋教育-做有情怀、有良心、有品质的职业教育机构

领取全套视频

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术要点  >  正文
分享到:

记一次OOM问题的解决

时间:2023-03-24 14:13     来源:千锋教育沈阳校区 作者:lx

  一. 问题概述

  老师的一个学生入职了杭州中通全球创研中心,最近他给老师分享一个他们公司解决OOM问题的案例,老师觉得十分有趣,特意把这个案例记录下来,日后我会做成教学案例分享给学生。这个问题发生的背景如下:

OOM问题的解决

  【在物流领域,针对各个下级网点而言,每月1日~9日是进行财务月结的重要时间节点。在这个关键节点上,各个网点需要使用导出功能输出寄派件、费用客户信息等多种信息进行汇总结算】。也就是说,在月初的时候,每个网点都要统计一个月的各种流水(寄件,收件等),最后再以excel表格的形式下载给客户。

  那么在这个业务中为什么很容易发生OOM异常呢?这是因为平均1个网点1个月的流水数据大约在30w行左右,根据计算得出大约500行数据就会占用1M内存,而1个站点把30万行一股脑地读到内存中,就会占用600M内存。试想一下,如果全国的网点都在月初集中下载报表的话,JVM是很容出现内存溢出的问题的!

  二. 解决方案

  那么这样一个棘手的问题,如果我们只用一个单一的解决方案是不够的,老师根据学生的描述,建议该学生主要采取以下几种解决方案。

  2.1 用硬盘空间置换内存空间

  如果我们在接到统计数据请求的时候,一次性把30w条数据从数据库读取到一个List集合中,这显然是不合理的,因为这样一个List集合就会占用600M内存。所以我们可以进行分页查询,每次查询1000条数据,然后往硬盘里写,多读取几次,一点一点的把所有的数据都读出来,再一点一点的往硬盘中写。这样在这个过程中,占用的内存就会少很多,主要变成了对硬盘空间的占用。而我们操作excel的技术,可以选择阿里巴巴的easyexcel。

  2.2 使用Mybatis的流式查询

  我们可以使用Mybatis的【流式查询】查询技术,在查询成功后返回的是一个迭代器而不是一个集合,应用每次都从迭代器中获取一条查询结果,能够降低内存的使用。试想一下,如果我们不使用流式查询,而想要一次性从数据库中读取30万条数据,内存是根本不够用的!这时我们只能选择分页查询,而分页查询的性能又取决于表设计以及索引的设计,大量数据分页查询的性能是很低的。老师对比了使用流式查询和分页查询的两种方案,得到的结论是取30万条数据时,流式查询的速度大约是分页查询的4~5倍左右。

  2.3 使用redission信号量限流

  生成一个月的流水报表是一个非常耗时的操作,用户也不可能马上就要结果,所以我这个学生的公司对同时生成报表的请求数量做了限制,同时只能处理10个报表的生成。在这期间如果再有生成报表的请求,我们将会让这些请求排队,等到前面的报表生成完毕后,再处理后面的请求。报表生成成功后,再通知客户主动去下载,老师建议这里使用redisson分布式锁的信号量来限制同时创建报表的线程数量。

  2.4 MQ解耦+微服务拆分

  本次业务中,读数据库,编写excel文件,上传到文件服务器这三个操作都非常耗时,学生的公司使用了MQ解耦,并把这次请求拆分成3个微服务,这样读、写、上传就不会相互影响了。

  三. 流式查询

  在这篇文章中,老师只给大家分享一下Mybatis流式查询的实现方法,其他的解决方案以后会在其他的文章中给大家呈现。

  3.1 概念

  流式查询就是查询成功后返回的是一个迭代器而不是一个集合,应用每次都从迭代器中获取一条查询结果,这样能够降低内存的使用。

  3.2 Mybatis实现流式查询

  接下来就是实现流失查询的具体过程。

  在mapper映射文件中,编写流式查询的逻辑。

  在mapper接口文件中添加selectFetchSize方法。

  // 参数 ResultHandler 是一个回调接口,也就是从游标中获得一条数据就会回调接口中的方法

  void selectFetchSize(ResultHandler handler);

  自己编写一个类实现ResultHandler接口,在该接口中定义从游标获得一条数据后的回调逻辑。

  /**

  * 通过流式查询每获得一条数据的回调类

  */

  public class TContentResultHandler implements ResultHandler {

  /**

  * 这里每集满1000条数据 往硬盘的excel文件中追加一次数据

  */

  private final static int BATCH_SIZE = 1000;

  /**

  * 计数器

  */

  private int size=0;

  /**

  * 存储每批数据的临时容器

  */

  private List tContents = new ArrayList<>();

  /**

  * 每从流式查询中获得一行结果,就会调用一次这个方法

  * @param resultContext

  */

  @Override

  public void handleResult(ResultContext resultContext){

  // 这里获取流式查询每次返回的单条结果

  TContent resultObject = resultContext.getResultObject();

  // 你可以看自己的项目需要分批进行处理或者单个处理,这里以分批处理为例

  tContents.add(resultObject);

  size++;

  if (size == BATCH_SIZE) {

  // 如果集满1000条就往文件中写一次

  handle();

  }

  }

  /**

  * 集满1000条 执行一次的逻辑

  */

  private void handle() {

  try {

  // 在这里可以对你获取到的批量结果数据进行需要的业务处理

  // 这里的业务是 往文件中写一次

  } finally {

  // 处理完每批数据后后将临时清空

  size = 0;

  tContents.clear();

  }

  }

  /**

  * 这个方法给外面调用,用来完成最后一批数据处理

  */

  public void end(){

  handle();// 处理最后一批不到BATCH_SIZE的数据

  }

  }

  在业务逻辑(service)层调用流式查询方法。

  @Autowired

  private TContentMapper contentMapper;

  public void streamQuery(){

  // 生成流式查询的回调对象

  TContentResultHandler tContentResultHandler = new TContentResultHandler();

  // 调用流式查询

  contentMapper.selectFetchSize(tContentResultHandler);

  // 执行完最后一批数据的逻辑

  tContentResultHandler.end();

  }

相关文章

  • 北京总部地址:北京市海淀区宝盛北里西区28号中关村智诚科创大厦4层
    北京沙河校区:北京市昌平区沙阳路18号北京科技职业技术学院广场服务楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 深圳校区地址:深圳市宝安区宝安大道5010号西部硅谷B座C区1层108
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 上海校区地址:上海市宝山区同济支路199号智慧七立方3号楼2-4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 广州校区地址:广州市白云区永平街永泰学山塘学山文化创意谷A1栋六楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 郑州二七区校区地址:郑州市二七区航海中路60号海为科技园C区10层
    郑州高新区校区地址:郑州市高新区金梭路与银杏路交叉口教育科技产业园南门D座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 大连校区地址:辽宁省大连市高新园区爱贤街10号大连设计城A座901
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 武汉金融港校区地址:武汉市东新区光谷大道77号金融港B18栋三、四层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 成都校区地址:成都市高新区肖家河沿街138号肖家河大厦三楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 西安校区地址:西安市雁塔区高新六路52号立人科技C座西区4楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 杭州旺田校区:浙江省杭州市上城区九堡镇旺田书画城A座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 青岛校区地址:青岛市市北区龙城路31号卓越世纪中心4号楼5层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 重庆校区地址:重庆市九龙坡区科园一路3号渝高大厦9楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 长沙校区地址:湖南省长沙市岳麓区麓谷企业广场A2栋三单元306号
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 哈尔滨校区地址:哈尔滨市松北区世泽路689号 科技创新城4号楼405
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 南京校区地址:南京市建邺区应天大街780号弘辉产业园1栋2层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 太原校区地址:太原市小店区长治路230号能源互联网大厦6层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 沈阳校区地址:辽宁省沈阳市浑南区世纪路16号东大软件园B园B1座A201
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 合肥校区地址:合肥市包河区徽州大道396号东方广场B座12A
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 贵阳校区地址:贵阳市云岩区延安东路37号物资大厦老楼9楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 济南校区地址:济南市历下区历山路36号齐鲁师范学院利宝产业大厦3F
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python人工智能+数据分析培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、网络安全培训、区块链培训、影视剪辑包装培训、游戏原画培训、全媒体运营培训
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 千锋教育服务号

    了解千锋动态
    关注千锋教育服务号

  • 千锋教育移动站

    扫一扫快速进入
    千锋移动端页面

  • 千锋互联服务号

    扫码匿名提建议
    直达CEO信箱