当前位置: 首页 > news >正文

Excel高性能异步导出完整方案!

前言

在大型电商系统中,数据导出是一个高频且重要的功能需求。

传统的同步导出方式在面对大数据量时往往会导致请求超时、内存溢出等问题,严重影响用户体验。

苏三商城项目创新性地设计并实现了一套完整的Excel异步导出机制,通过注解驱动、任务队列、定时调度、消息通知等技术手段,完美解决了大数据量导出的技术难题,成为项目的重要技术亮点。

系统架构设计

整体架构图

e5a78da6-6b82-40f7-9573-d00aa7dcd0d7 (1)

核心组件说明

  1. 注解驱动层:通过@ExcelExport注解实现声明式编程

  2. 切面处理层CommonTaskAspect负责拦截和任务创建

  3. 任务管理层ExcelExportTask执行具体的导出逻辑

  4. 调度引擎层:基于Quartz的定时任务调度

  5. 消息通知层:RocketMQ + WebSocket实现异步通知

  6. 存储层:MySQL存储任务状态,OSS存储导出文件

异步导出流程详解

完整流程图

505c0b6a-9d51-4064-9361-9ce57347715e (1)

关键步骤分析

1. 注解驱动任务创建
@ExcelExport(ExcelBizTypeEnum.USER)
@ApiOperation(notes = "导出用户数据", value = "导出用户数据")
@PostMapping("/export")
public void export(HttpServletResponse response, UserConditionEntity userConditionEntity) {// 方法体可以为空,切面会自动处理
}

设计亮点

  • 声明式编程:通过注解实现功能声明,代码简洁

  • 零侵入性:业务方法无需修改,切面自动处理

  • 类型安全:通过枚举确保业务类型的正确性

2. 切面拦截与任务创建
@Aspect
@Component
public class CommonTaskAspect {@Before("@annotation(cn.net.susan.annotation.ExcelExport)")public void before(JoinPoint joinPoint) throws Throwable {// 获取注解信息ExcelBizTypeEnum excelBizTypeEnum = method.getAnnotation(ExcelExport.class).value();// 创建任务实体CommonTaskEntity commonTaskEntity = createCommonTaskEntity(excelBizTypeEnum);// 保存任务到数据库commonTaskMapper.insert(commonTaskEntity);}
}

技术特色

  • AOP切面编程:实现横切关注点的分离

  • 反射机制:动态获取注解信息和方法参数

  • 任务持久化:将任务信息保存到数据库,确保可靠性

3. 定时任务调度机制
@Component
public class CommonTaskJob extends BaseJob {@Overridepublic JobResult doRun(String params) {// 查询待执行任务CommonTaskConditionEntity condition = new CommonTaskConditionEntity();condition.setStatusList(Arrays.asList(TaskStatusEnum.WAITING.getValue(),TaskStatusEnum.RUNNING.getValue()));List<CommonTaskEntity> tasks = commonTaskMapper.searchByCondition(condition);// 执行任务for (CommonTaskEntity task : tasks) {AsyncTaskStrategyContextFactory.getInstance().getStrategy(task.getType()).doTask(task);}return JobResult.SUCCESS;}
}

核心机制

  • 定时扫描:通过Quartz定时扫描任务队列

  • 策略模式:根据任务类型选择对应的处理器

  • 并发处理:支持多个任务并发执行

4. 异步任务处理器
@AsyncTask(TaskTypeEnum.EXPORT_EXCEL)
@Service
public class ExcelExportTask implements IAsyncTask {@Overridepublic void doTask(CommonTaskEntity commonTaskEntity) {try {// 1. 更新任务状态为执行中commonTaskEntity.setStatus(TaskStatusEnum.RUNNING.getValue());commonTaskMapper.update(commonTaskEntity);// 2. 获取业务类型和请求参数ExcelBizTypeEnum excelBizTypeEnum = getExcelBizTypeEnum(commonTaskEntity.getBizType());String requestParam = commonTaskEntity.getRequestParam();Object toBean = JSONUtil.toBean(requestParam, aClass);// 3. 获取对应的Service并执行导出String serviceName = this.getServiceName(requestEntity);BaseService baseService = (BaseService) SpringBeanUtil.getBean(serviceName);String fileName = getFileName(excelBizTypeEnum.getDesc());String fileUrl = baseService.export(toBean, fileName, this.getEntityName(requestEntity));// 4. 更新任务状态为成功commonTaskEntity.setFileUrl(fileUrl);commonTaskEntity.setStatus(TaskStatusEnum.SUCCESS.getValue());} catch (Exception e) {// 5. 处理失败情况handleTaskFailure(commonTaskEntity, e);} finally {// 6. 更新任务记录并发送通知commonTaskMapper.update(commonTaskEntity);sendNotifyMessage(commonTaskEntity);}}
}

处理流程

  • 状态管理:完整的任务状态流转(等待→执行中→成功/失败)

  • 异常处理:完善的异常捕获和失败重试机制

  • 动态调用:通过反射动态获取Service实例

  • 通知机制:任务完成后自动发送通知

5. 消息通知机制
@RocketMQMessageListener(topic = "${mall.mgt.excelExportTopic:EXCEL_EXPORT_TOPIC}",consumerGroup = "${mall.mgt.excelExportGroup:EXCEL_EXPORT_GROUP}"
)
@Component
public class ExcelExportConsumer implements RocketMQListener<MessageExt> {@Overridepublic void onMessage(MessageExt message) {String content = new String(message.getBody());CommonNotifyEntity commonNotifyEntity = JSONUtil.toBean(content, CommonNotifyEntity.class);pushNotify(commonNotifyEntity);}private void pushNotify(CommonNotifyEntity commonNotifyEntity) {// 通过WebSocket推送通知WebSocketServer.sendMessage(commonNotifyEntity);// 更新通知状态commonNotifyEntity.setIsPush(1);commonNotifyMapper.update(commonNotifyEntity);}
}

通知特色

  • 异步解耦:通过消息队列实现系统解耦

  • 实时推送:WebSocket确保用户及时收到通知

  • 可靠性保证:消息队列确保通知的可靠传递

技术架构亮点

1. 策略模式 + 工厂模式

public class AsyncTaskStrategyContextFactory {private static Map<Integer, IAsyncTask> asyncTaskMap;public IAsyncTask getStrategy(Integer taskType) {return asyncTaskMap.get(taskType);}
}

设计优势

  • 扩展性强:新增任务类型只需实现IAsyncTask接口

  • 维护性好:每种任务类型独立实现,互不影响

  • 配置灵活:通过工厂模式统一管理任务策略

2. 注解驱动编程

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelExport {ExcelBizTypeEnum value();
}

编程范式

  • 声明式编程:通过注解声明功能,而非命令式实现

  • 元数据驱动:注解携带的元数据驱动系统行为

  • 代码简洁:业务代码保持简洁,关注点分离

3. 异步任务状态机

66b3344f-aa5e-4607-9e0d-6389c5797a7c (1)

状态管理

  • 状态流转:清晰的状态转换逻辑

  • 重试机制:失败任务自动重试,提高成功率

  • 状态持久化:任务状态持久化到数据库

4. 分页大数据处理

private String doExport(V v, String fileName, String clazzName) {RequestConditionEntity conditionEntity = (RequestConditionEntity) v;// 计算分页参数int totalCount = getBaseMapper().searchCount(conditionEntity);int sheetCount = totalCount % sheetDataSize == 0 ? totalCount / sheetDataSize : totalCount / sheetDataSize + 1;// 创建ExcelWriterExcelWriter excelWriter = EasyExcel.write(file).build();// 分页处理数据for (int sheetIndex = 1; sheetIndex <= sheetCount; sheetIndex++) {List<K> dataEntities = getBaseMapper().searchByCondition(conditionEntity);// 写入数据到SheetWriteSheet writeSheet = EasyExcel.writerSheet("Sheet" + sheetIndex).head(Class.forName(clazzName)).build();excelWriter.write(dataEntities, writeSheet);conditionEntity.setPageNo(conditionEntity.getPageNo() + 1);}excelWriter.finish();return uploadToOSS(file);
}

处理策略

  • 内存优化:分页查询避免大量数据加载到内存

  • 流式处理:使用EasyExcel的流式API

  • 多Sheet支持:大数据自动分割到多个Sheet

  • 进度可控:分页处理便于监控和中断

技术优势

1. 用户体验优势

  • 即时响应:用户请求后立即返回,无需等待

  • 实时通知:通过WebSocket实时推送导出结果

  • 进度可见:用户可以实时查看导出进度

  • 错误友好:导出失败时提供详细的错误信息

2. 系统性能优势

  • 高并发:异步处理支持高并发导出请求

  • 资源优化:分页处理避免内存溢出

  • 负载均衡:任务队列支持负载均衡

  • 可扩展性:支持水平扩展和垂直扩展

3. 开发维护优势

  • 代码简洁:注解驱动,业务代码简洁

  • 易于扩展:新增业务类型只需添加注解

  • 统一管理:所有导出任务统一管理和监控

  • 错误处理:完善的异常处理和重试机制

4. 运维管理优势

  • 任务监控:完整的任务执行监控

  • 状态管理:清晰的任务状态流转

  • 日志记录:详细的操作日志记录

  • 告警机制:完善的异常告警机制

总结

苏三商城的Excel异步导出机制是一个设计精良、功能完善的企业级解决方案。

它通过以下技术手段实现了高效、稳定、可扩展的异步导出功能:

核心技术栈

  • 注解驱动@ExcelExport注解实现声明式编程

  • AOP切面CommonTaskAspect实现横切关注点分离

  • 策略模式AsyncTaskStrategyContextFactory实现任务策略管理

  • 定时调度:Quartz实现任务定时调度

  • 消息队列:RocketMQ实现异步通知

  • 实时通信:WebSocket实现实时推送

  • 文件存储:OSS实现文件云端存储

设计亮点

  1. 异步解耦:通过任务队列实现请求与处理的解耦

  2. 状态管理:完整的任务状态流转和持久化

  3. 错误处理:完善的异常处理和重试机制

  4. 性能优化:分页处理、流式写入、内存优化

  5. 扩展性强:支持业务类型、导出格式、通知方式的扩展

  6. 监控完善:完整的任务监控和告警机制

业务价值

  • 提升用户体验:异步处理避免长时间等待

  • 提高系统性能:支持大数据量导出和高并发请求

  • 降低开发成本:注解驱动减少重复代码

  • 便于运维管理:统一的任务管理和监控

这套异步导出机制不仅解决了传统同步导出的技术难题,还提供了良好的扩展性和维护性,是苏三商城项目的技术亮点之一,值得在其他项目中推广和应用。

文章转载自:苏三说技术

原文链接:https://www.cnblogs.com/12lisu/p/19169750

体验地址:http://www.jnpfsoft.com/?from=001YH

http://www.dtcms.com/a/540352.html

相关文章:

  • 网站正在建设 敬请期待免费的cms模板
  • 输电线路绝缘子缺陷检测图像数据集VOC+YOLO格式1578张3类别
  • 跨文化理解的困境与AI大模型作为“超级第三方“的桥梁作用
  • JDK版本管理工具JVMS
  • 【JUnit实战3_18】第十章:用 Maven 3 运行 JUnit 测试(上)
  • SQLite 核心知识点讲解
  • JAiRouter v1.1.0 发布:把“API 调没调通”从 10 分钟压缩到 10 秒
  • 自建网站如何赚钱c2c模式为消费者提供了便利和实惠
  • Lua-编译,执行和错误
  • Lua与LuaJIT的安装与使用
  • 数独生成题目lua脚本
  • 影响网站加载速度wordpress获得当前文章的相关文章
  • Hive 技术深度解析与 P7 数据分析架构师多行业全场景实战课程合集(视频教程)
  • 嘉兴高端网站建设公司网络安全等级保护
  • HOW - localstorage 超时管理方案
  • java如何判断上传文件的类型,不要用后缀名判断
  • 【Linux】系统备份与恢复:rsync 与 tar 的完整使用教程
  • ROS2系列(3):第一个C++节点
  • zookeeper是什么
  • 构建“全链路解决方案”:解决集团化医院信创的三重难题
  • 网站建设区别广安市邻水建设局网站
  • 网站中的文字滑动怎么做化妆品网站建设策略
  • 【Netty4核心原理⑮】【Netty 编解码的艺术】
  • PHP-Casbin 在分布式服务中利用 Watcher 做策略同步
  • OCP考试必须培训吗?费用多少?
  • SpringBoot + 百度内容安全实战:自定义注解 + AOP 实现统一内容审核(支持文本 / 图片 / 视频 + 白名单 + 动态开关)
  • 心智结构与组织学习
  • NAS 私有云零信任部署:cpolar 加密访问 + 本地存储,破解安全与便捷难题
  • C++面向对象继承全面解析:不能被继承的类、多继承、菱形虚拟继承与设计模式实践
  • 只做财经的网站厦门高端网站建设公