图片导入导出优化记录

图片导入导出优化记录

图片导入

功能描述:本系统需要将A平台的图片转存到B平台中,流程是下载A中的图片,调用B的上传接口上传。

问题点:排查发现每张图片都要耗时150ms,多张图片是并行执行,但是3000张图片要传10多分钟。其实一张图片也就600kb左右。

数据流程:梳理流程发现,

1、定时任务每次处理200个后,不再继续处理。也就是等到下1分钟,才会执行后面的下载任务,这样计算,3000张的上传主要就是受到这个影响。

2、每次子任务上传成功后,更新总任务的成功个数。在并发场景下,数据库单条数据频繁更新,也会导致等待时间长,计数不准的情况。

3、下图更新所有图片为上传中的状态,是串行进行。

优化方案

1、每次传完之后就轮询搜索下200个进行上传。并且把任务改为上传进行中,这样,就算到下一分钟,也不会查到本次任务查到的所有待上传的素材。

2、后续将此计数过程,由缓存记录。等到所有任务处理完毕,再将缓存更新到数据库。

3、图片的上传状态互不影响,可以改为并行处理。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

图片导出

功能描述:勾选多个图片,点击导出,在浏览器上下载图片包zip文件。

问题点:下载3000张图片,需要耗时3分钟。

数据流程:3000张按照500一个批次去处理,但是500个是串行下载,下载一个用zipoutputstream写一次流。使用arthas验证了,一张170ms,两张 282ms,说明是串行执行,如果是3000张,约300s也就是5分钟。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

优化方案:并发下载,每500个的缓存下载的数据,一起交给zipoutputstream输出。

 			ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
            for (Map.Entry<String, byte[]> picMap : rstMap.entrySet()) {
                String name = picMap.getKey();
                zos.putNextEntry(new ZipEntry(name));
                int data = 0;
                ByteArrayInputStream bais = new ByteArrayInputStream(picMap.getValue());
                byte[] buffer = new byte[2 * BisConstants.MULTIPLE_10 * BisConstants.MB_SIZE];
                while ((data = bais.read(buffer, 0, BisConstants.MULTIPLE_10 * BisConstants.MB_SIZE)) != -1) 				{
                    zos.write(buffer, 0, data);
                }
            }
            // 导出到浏览器
            zos.flush();
            zos.closeEntry();

picMap是下载好的数据<String, byte[]>

优化效果:1000张耗时20s内。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

方法执行的工具:

https://arthas.aliyun.com/doc/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
帮我优化以下代码,不使用ADO ,然后每次导出不同的10000条记录至新的EXECL文件中:Dim strSQL As String Dim strFileName As String Dim i As Long Dim batchSize As Long '每批次导出记录数 Dim batchCount As Long '批次计数器 Dim exportCount As Long '导出计数器 '设置导出文件路径和文件名 strFileName = "C:\Users\icd\Desktop\流水分割\" batchSize = 10000 '每批次导出记录数 DoCmd.SetWarnings False '暂时关闭Access的警告信息 DoCmd.RunSQL "SELECT 导出数据.* INTO ExportData FROM 导出数据" '将表导入临时表ExportData DoCmd.SetWarnings True '重新开启Access的警告信息 Set rs = CurrentDb.OpenRecordset("SELECT * FROM ExportData", dbOpenSnapshot) '打开临时表ExportData '循环导出数据 Do While Not rs.EOF If exportCount Mod batchSize = 0 Then '每批次导出到一个新的文件 If exportCount <> 0 Then DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "ExportData", strFileName & Format(batchCount, "000000") & ".xlsx", True End If batchCount = batchCount + 1 End If exportCount = exportCount + 1 rs.MoveNext Loop '导出最后一份文件 If exportCount Mod batchSize <> 0 Then DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "ExportData", strFileName & Format(batchCount, "000000") & ".xlsx", True End If rs.Close Set rs = Nothing DoCmd.SetWarnings False '暂时关闭Access的警告信息 DoCmd.RunSQL "DROP TABLE ExportData" '删除临时表ExportData DoCmd.RunSQL "DELETE 导出数据.* FROM 导出数据" '删除导出数据内容 DoCmd.SetWarnings True '重新开启Access的警告信息
06-09

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值