随手记录导入导出功能

这段时间忙于业务,貌似没有什么可以拿出来写写的。就说下最近做的导出功能吧。(ps,其实就是同步改成异步,也没什么好说的。)

需求:

1,管理后台需要导出订单表。月末的时候财务可能会频繁导出。这里假设使用阿里巴巴的easy excel,这样会节省很多内存。假设一次需要导出5兆的文件,一次导出处理需要10s左右,那么如果在同一个10秒中有1000个导出请求,5*1000=5000兆约等于5g,服务器会炸的。

2,如果服务器重启,用户的导出请求不可以失败。

其实一眼看起来,这个需要很简单,只要使用个消息队列就行了,把过来的请求丢到队列中,一个一个消费,这样服务器就不会out of memory,同时如果服务器重启,消息不会受到影响。但是抱歉,项目中没有使用消息队列。

消息队列 ≈ MySQL+定时任务

方案:

1,每次用户导出请求,封装成一个任务。插入MySQL任务表,同时立即返回任务id。异步触发一下定时任务方法。这里的定时任务也就是消费者,不停的消费没有完成的任务。当任务完成,将数据写回到数据库,并且标记已消费。

2,让前端轮询此id对应的任务是否导出完毕。

3,如果任务ok,通过任务id,MySQL直接读表返回文件流。

注意的细节:

1,这里的定时任务可以多开几个线程,加速处理。最常用的就是查询出任务列表,对列表索引对线程数取余,分成线程数个组。并行处理。

2,MySQL有种类型为blob,专门用来存储二进制流的。

3,在使用jdbc操作数据库的时候,如果传参byte[]到sql语句中呢。我们可以使用java.sql.PreparedStatement ps,然后用ps.setBlob(index, arg),这样的方式丢过去。如果使用spring提供的JdbcTemplate的话,直接实现下org.springframework.jdbc.core.PreparedStatementCreator这个接口就行。

隐患:

其实直接丢在MySQL是不大合适的,应该丢在redis或者mongodb中去。因此同时下载的话,因为如果同时时间大家的任务都ok了的话,都去直接到MySQL中fetch data,这样MySQL可能扛不住。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值