Spring Boot + RabbitMQ 实现导出任务异步处理

  1. 引入依赖

  2. RabbitMQ 基础配置

  3. RabbitMQ 配置类

  4. 发送异步导出任务

  5. 消费者监听任务

  6. 任务实体类结构说明

  7. 引入 RabbitMQ 依赖

在 pom.xml 中添加 Spring Boot AMQP 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

此依赖包含 RabbitTemplate、@RabbitListener 等核心功能。

配置文件(application.yml)

spring:
  data:
    rabbitmq:
      # RabbitMQ 服务器地址
      host: ${RABBITMQ_HOST:192.168.1.1}

      # 端口
      port: ${RABBITMQ_PORT:6672}

      # 用户名、密码
      username: ${RABBITMQ_USERNAME:root}
      password: ${RABBITMQ_PASSWORD:123456}

      # 虚拟机(推荐按项目隔离)
      virtual-host: ${RABBITMQ_VIRTUAL:/project}

      listener:
        type: simple
        simple:
          retry:
            enabled: true       # 开启消费失败重试
            max-attempts: 3     # 最大重试次数(含首次)
          default-requeue-rejected: true  # 超过重试后是否重新入队
          auto-startup: true    # 项目启动时自动开启监听

RabbitMQ 配置类

@Configuration
public class RabbitConfig {

    /**
     * 创建 Topic 类型交换机
     */
    @Bean
    public Exchange exchange() {
        return ExchangeBuilder.topicExchange("exchange").durable(true).build();
    }

    /**
     * 创建 JSON 消息转换器(对象自动转 JSON)
     */
    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

发送异步导出任务(生产者)

public AjaxResult exportBranchClearingRatio(BranchClearingRatioQueryReq queryReq) {

    // 构建导出任务
    ReportTask task = ReportTask.builder()
            .taskCode(ReportTaskEnum.EXPORT_BRANCH_CLEARING_RATIO.getCode())
            .taskType(ReportTaskType.EXPORT.getValue())
            .taskStatus(ReportTaskStatus.HANDLEING.getValue())
            .taskName(ReportTaskEnum.EXPORT_BRANCH_CLEARING_RATIO.getDesc())
            .requestUrl("")
            .taskKey(ReportTaskEnum.EXPORT_BRANCH_CLEARING_RATIO.getKey())
            .paramJson(JSONUtil.toJsonStr(queryReq))
            .build();

    // 保存任务记录
    boolean save = reportTaskService.save(task);
    Assert.isTrue(save, () -> new RuntimeException("导出任务失败, 请稍后重试"));

    // 封装 MQ 消息
    ExportTask exportTask = new ExportTask();
    exportTask.setTaskId(task.getId());
    exportTask.setExportType(ReportTaskEnum.EXPORT_BRANCH_CLEARING_RATIO.getCode());

    // 发送到交换机
    rabbitTemplate.convertAndSend("exchange", "topic.excelExportTask", exportTask);

    return AjaxResult.ok();
}

消费者(监听导出任务)

@Component
@RabbitListener(queues = "EXCEL_EXPORT_TASK")
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ExportTaskReceive {

    private final ExportTaskConsumer excelExportTaskInvoice;

    @RabbitHandler
    public void handle(ExportTask exportTask){
        try {
            excelExportTaskInvoice.handleData(exportTask);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ReportTask 实体类

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@Builder
@TableName("t_report_task")
public class ReportTask extends BaseEntity implements Serializable {

    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    private String taskCode;       // 任务编号
    private Integer taskType;      // 1-导出;2-导入
    private Integer taskStatus;    // 任务状态:处理中/成功/失败
    private String taskName;       // 任务名称
    private String requestUrl;     // 对应接口路径
    private String taskKey;        // 队列路由 key
    private String paramJson;      // 请求参数 JSON
    private String errorMsg;       // 错误信息
    private String fileUrl;        // 文件下载路径
}
### Spring Boot 延迟导出功能的最佳实践 在 Spring Boot实现延迟导出功能,可以通过多种方式结合框架特性来优化性能和可靠性。以下是几种常见且高效的做法: #### 1. 使用 `@Scheduled` 注解实现固定延迟的导出任务 通过 `@Scheduled` 注解可以轻松定义基于时间的延迟任务。这种方式适用于需要定期执行的导出操作。 ```java import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class ExportTask { @Scheduled(fixedDelay = 5000) // 每次任务完成后延迟5秒再执行 public void performExport() { System.out.println("开始执行延迟导出任务..."); // 导出逻辑 try { Thread.sleep(2000); // 模拟耗时操作 System.out.println("延迟导出任务完成!"); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 上述代码中,`fixedDelay` 参数确保每次任务完成后等待指定时间再执行下一次[^3]。 #### 2. 结合 `@Async` 实现异步导出 对于需要立即返回响应但实际导出操作耗时较长的场景,可以使用 `@Async` 注解将导出任务放入后台线程池中执行。 ```java import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class ExportService { @Async public void exportData() { System.out.println("开始异步导出任务..."); // 导出逻辑 try { Thread.sleep(2000); // 模拟耗时操作 System.out.println("异步导出任务完成!"); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 需要注意的是,使用 `@Async` 时必须确保配置了相应的线程池[^3]。 #### 3. 利用消息队列实现可靠的延迟导出 在分布式系统中,可以结合消息队列(如 RabbitMQ 或 Kafka)实现更灵活的延迟导出机制。生产者将导出请求发送到队列中,消费者按需处理这些请求。 **生产者代码示例:** ```java import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class ExportProducer { @Autowired private RabbitTemplate rabbitTemplate; public void sendExportRequest(String message) { rabbitTemplate.convertAndSend("exportQueue", message); System.out.println("导出请求已发送:" + message); } } ``` **消费者代码示例:** ```java import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Service; @Service public class ExportConsumer { @RabbitListener(queues = "exportQueue") public void receiveExportRequest(String message) { System.out.println("收到导出请求:" + message); // 导出逻辑 try { Thread.sleep(2000); // 模拟耗时操作 System.out.println("导出任务完成:" + message); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 这种方式不仅能够实现延迟导出,还能提高系统的可靠性和可扩展性[^4]。 #### 4. 使用 `CompletableFuture` 处理复杂导出逻辑 当导出任务涉及多个步骤或依赖其他服务时,可以使用 `CompletableFuture` 来简化异步编程模型。 ```java import java.util.concurrent.CompletableFuture; public class CompletableFutureExample { public CompletableFuture<String> exportDataAsync() { return CompletableFuture.supplyAsync(() -> { System.out.println("开始异步导出任务..."); try { Thread.sleep(2000); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("异步导出任务完成!"); return "导出成功"; }); } } ``` `CompletableFuture` 提供了强大的链式调用能力,适合处理复杂的异步流程[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值