百万数据导出

做项目我们经常会遇到的一个需求就是:导出

而当数据较多时,导出又会时常出现OOM,甚至引发雪崩连锁效应,不巧的是我们前段时间正在生产经历这种问题:单月百万左右订单,微服务架构,导出订单这个功能正巧落在订单服务,然后因此次导出导致OOM,继而出现雪崩,依赖的服务相继“跪下”了,现场情况大致如下

百万数据导出_第1张图片

下面看看如何在有限的内存中导出大量的数据


面临问题:

        1. 同步导出容易接口超时(读超时)

        2. 同步导出容易OOM(数据量太大)

        3. 数据量太大 或 SQL不精简导致慢

        4. 业务需求:数据需要聚合 或 相同商品放在一起 或 按某些规则排序

        5. 如果是异步,用户怎么拿到数据

        6. excel太大,用户打不开咋整

如何实现:

        异步导出、使用easyExcel、分页查询数据、计算limit起始位置、Mysql断点续传(少量多次)、文件上传到OSS、使用websocket通知 或 生成导出记录用户主动回查、多个sheet、总条数可配置、去掉count查询、order by 商品,聚合等业务处理

基于上面几个问题,学习下此方案里面的业务流程:

        1. 异步导出

                使用job记录 或 MQ 或 异步业务处理

        2. 使用easyExcel

                相比poi jxl来说更加省内存(具体有待验证)

        3. 分页查询

                可以采用分页,也可以采用 断点续传,本质都是可以减少内存占用(mysql占用内存 加载到jvm中占用特别大)

        4. 多个sheet页

                单页支持1048576行数据,有的版本行数过多打不开

                也可拆分为多个excel文件后再次压缩[Java-压缩方案对比-CSDN博客]

                如业务允许也可导出为cvs文件

        5. 计算起始页

                如果是多个sheet页/多excel文件 则需要关心这个问题

        6. 文件上传到OSS

                一般建议将应用服务器和文件服务器分开,应用服务器需要更多的内存资源或者CPU资源,而文件服务器需要更多的磁盘资源。而且用应用服务器会占用很多的宽带资源

        7. 通过websocket通知

                一般项目中都集成了Msg模块(站内信),用来向用户推送消息

                如果没有的话,可以做一个 通知表,记录标题 用户 附加地址 下载地址 阅读状态等信息

百万数据导出_第2张图片

        8. 总条数可配置

                可以根据条件取小部分数据,业务有时候并没有必要取所有数据,节省资源


改造前流程:

百万数据导出_第3张图片

改造后流程:

百万数据导出_第4张图片

你可能感兴趣的:(java,excel)