Excel导入功能频繁使用导致系统卡顿,优化方法及代码实例,实例可直接运行

Excel导入功能频繁使用导致系统卡顿,其根本原因通常可以归结为资源消耗过大,并且这些消耗集中在几个关键点上。

性能变差的原因分析

  1. 内存问题
    全量加载模型:最常用的Apache POI库中的XSSFWorkbook(用于.xlsx文件)会将整个Excel文件解析为DOM对象并全部加载到内存中。一个几十兆的Excel文件,其内存占用可能达到文件大小的5-10倍甚至更高。频繁导入会迅速消耗JVM堆内存,导致频繁的Full GC,使系统暂停(Stop-The-World),表现就是卡顿。
    对象创建与回收:在解析和数据处理过程中,会创建大量的临时对象(如String, Cell, Row等),给垃圾回收器带来巨大压力。
  2. I/O 与 数据库 问题
    数据库连接耗尽:如果导入是同步的,并且每条记录都单独执行一次INSERT操作,会导致数据库连接被长时间占用。并发导入请求稍高时,连接池中的连接会被迅速耗尽,新的请求只能等待,导致系统响应变慢甚至超时。
    频繁的数据库交互:N+1问题。逐条插入会产生大量网络往返和事务日志,效率极低。
    大事务:如果将整个导入过程放在一个数据库事务中,对于大数据量的导入,事务会非常长,可能持有数据库锁很长时间,影响其他业务操作。
  3. CPU 问题
    XML解析开销:.xlsx文件本质上是ZIP压缩包内的一系列XML文件。使用XSSFWorkbook解析XML需要大量的CPU计算。
    复杂的业务逻辑:在导入过程中,可能包含了大量的数据校验、格式转换、数据关联查询(如根据名称查ID)等CPU密集型操作,进一步加剧了CPU的负担。
  4. 线程阻塞问题
    同步处理:导入任务在Web容器的HTTP线程(如Tomcat的worker线程)中同步执行。导入通常比较耗时,这会长时间占用该线程,导致Tomcat线程池被占满,无法处理其他用户请求。

11

优化方案
优化需要从技术选型、架构设计和代码层面多管齐下。

  1. 核心技术选型优化:使用流式读取
    这是解决内存问题的最有效手段。放弃全量加载的XSSFWorkBook,改用POI提供的事件模型 API。

推荐使用:XSSF and SAX (Event API) 原理:类似于XML的SAX解析,逐行扫描Excel文件内容,触发事件(如“开始一行”、“读取一个单元格”),在回调函数中处理数据。它不会将整个文件加载到内存,内存占用极低(基本恒定,与文件大小无关)。
替代库:EasyExcel(阿里开源组件) 这是对POI事件模型的二次封装,API更简单易用,并内置了内存优化等特性,强烈推荐。 它通过注解和监听器模式,让你能更专注于业务逻辑。
示例对比:

优化前(XSSFWorkbook - 内存杀手): 不推荐!文件越大,内存占用越高。
优化后(EasyExcel - 流式): 推荐!内存占用低且恒定 。
2. 数据库操作优化:批量插入
使用JDBC Batch:将多条INSERT或UPDATE语句打包成一个批次,一次性发送给数据库,极大地减少了网络往返和数据库事务开销。
结合MyBatis等ORM框架:在MyBatis中,可以在Mapper中配置 foreach 标签,但更推荐使用 ExecutorType.BATCH 模式。
控制批次大小:每处理一定数量的数据(如1000条)就执行一次批量插入,然后清空批次。
3. 架构设计优化:异步处理 + 解耦
这是解决用户体验和系统稳定性的关键。

方案:用户提交Excel文件后,后端立即返回一个任务ID(如taskId),然后将导入任务提交到线程池或消息队列中异步执行。
流程: 用户上传Excel,接口立即返回 { "success": true, "taskId": "123456" }。 后端将任务放入线程池队列。 前端轮询或用WebSocket询问任务状态(如“处理中”、“成功”、“失败及原因”)。
好处: 释放HTTP线程:Tomcat线程可以快速回收,处理更多请求。 提升用户体验:用户无需长时间等待,页面不会“卡死”。 可控的并发:通过线程池大小控制同时导入的任务数,避免系统过载。
4. 业务逻辑与数据处理优化
减少数据库查询:在循环内部避免进行单条查询。例如,如果需要根据“用户名”查“用户ID”,可以先将所有用户名收集到一个Set中,然后通过一次IN查询获取所有ID映射,再在内存中组装。
数据预处理:在流式读取的监听器中,只做最简单的校验和转换。复杂的业务规则校验可以放在批量插入之前的一个统一步骤中。
合理使用事务:对于大批量导入,不要用一个事务覆盖全程。可以每插入一个批次就提交一次事务,避免产生大事务。
5. JVM 与 运维层面优化
调整JVM参数:适当增加堆内存(-Xmx),但这不是根本解决办法,核心还是优化代码。
监控:使用APM工具(如SkyWalking, Prometheus + Grafana)监控系统关键指标:JVM内存/GC、数据库连接池、CPU使用率、接口响应时间。通过监控定位瓶颈。
根据以上优化方案,我写一个Excel导入的代码实现,仅供参考,项目可直接运行看效果,代码下载方法如下:
1、关注公众号:

诗情画意小芳

2、发送内容: excel上传实例

3、会自动返回下载地址。

posted @ 2025-12-02 10:24  程序员老王头  阅读(43)  评论(0)    收藏  举报