首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >订单下单后异步处理

订单下单后异步处理

原创
作者头像
botkenni
发布2026-06-12 09:08:34
发布2026-06-12 09:08:34
1390
举报
文章被收录于专栏:IT码农IT码农

一、典型业务场景:订单下单后异步处理

1. 业务背景

电商 / 进销存系统,用户提交订单,核心主流程:创建订单 → 扣减库存 → 支付跳转。

下单成功后,还有一系列非强依赖、耗时较长的附属操作:

  1. 发送下单短信 / 站内通知
  2. 推送订单消息至消息中心
  3. 生成订单对账日志、统计业务数据
  4. 异步更新用户消费积分

原有同步方案问题

所有逻辑串行执行,接口响应慢、超时风险高;某一个附属操作报错,会直接导致整个下单流程失败,容错性差。

2. 异步实现方案选型

基于你的技术栈,提供两种主流方案:

  • 方案一:Spring 内置异步 @Async(简单场景、单体应用)
  • 方案二:消息队列(RocketMQ/Kafka)(分布式、高并发、可靠场景,企业主流)

二、方案一:Spring @Async 异步(单体应用、简单场景)

1. 前置配置

1.1 开启异步注解

启动类添加 @EnableAsync

importorg.springframework.boot.SpringApplication;

importorg.springframework.boot.autoconfigure.SpringBootApplication;

importorg.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication

@EnableAsync// 开启Spring异步支持

publicclassOrderApplication{

publicstaticvoidmain(String[] args){

SpringApplication.run(OrderApplication.class, args);

}

}

2. 核心代码分层

2.1 订单主服务(同步核心流程)

importorg.springframework.stereotype.Service;

importjavax.annotation.Resource;

@Service

publicclassOrderService{

@Resource

privateOrderAsyncService orderAsyncService;

/**

* 下单主流程(同步执行核心逻辑)

*/

publicStringcreateOrder(Long userId,Long goodsId,Integer num){

// 1. 核心同步操作:创建订单、扣库存(必须保证事务一致性)

String orderNo =generateOrderNo();

saveOrder(orderNo, userId, goodsId, num);

deductStock(goodsId, num);

// 2. 附属操作:调用异步方法,主线程直接放行,不等待执行结果

orderAsyncService.afterOrderSuccess(orderNo, userId);

// 主线程快速响应前端

return"下单成功,订单号:"+ orderNo;

}

// 模拟生成订单号

privateStringgenerateOrderNo(){

return"ORD"+System.currentTimeMillis();

}

// 模拟保存订单

privatevoidsaveOrder(String orderNo,Long userId,Long goodsId,Integer num){}

// 模拟扣减库存

privatevoiddeductStock(Long goodsId,Integer num){}

}

2.2 异步服务(@Async 标记异步方法)

importorg.springframework.scheduling.annotation.Async;

importorg.springframework.stereotype.Service;

@Service

publicclassOrderAsyncService{

/**

* 订单成功后异步执行附属逻辑

*/

@Async

publicvoidafterOrderSuccess(String orderNo,Long userId){

// 1. 发送短信通知

sendSms(userId, orderNo);

// 2. 推送站内消息

pushMessage(userId, orderNo);

// 3. 记录对账日志

recordAccountLog(orderNo);

// 4. 增加用户积分

addUserPoints(userId,10);

}

privatevoidsendSms(Long userId,String orderNo){

// 模拟调用短信接口,耗时操作

}

privatevoidpushMessage(Long userId,String orderNo){}

privatevoidrecordAccountLog(String orderNo){}

privatevoidaddUserPoints(Long userId,Integer points){}

}

3. 执行流程

  1. 前端请求下单接口,主线程执行创建订单、扣库存核心逻辑;
  2. 调用 afterOrderSuccess 方法,Spring 自动分配独立子线程执行;
  3. 主线程不阻塞,直接返回结果给前端,接口响应速度大幅提升;
  4. 子线程后台慢慢执行短信、积分、日志等操作。

4. 优缺点

  • 优点:接入简单、零中间件、开发成本低;
  • 缺点:无持久化,服务重启 / 宕机,异步任务丢失;不适合分布式、高并发场景。

三、方案二:消息队列异步(RocketMQ,分布式 / 高并发 / 企业级)

适用于微服务、集群部署、要求消息不丢失、可重试的生产环境。

1. 整体架构流程

  1. 订单服务:完成创建订单 + 扣库存核心同步逻辑;
  2. 订单服务向 RocketMQ 发送「订单成功」消息;
  3. 主线程直接响应前端;
  4. 独立消费者服务监听消息队列,消费消息,执行短信、积分、日志等操作;
  5. 支持消息重试、死信队列,保证任务最终执行成功。

2. 核心代码(简化版)

2.1 消息生产者(订单服务)

importorg.apache.rocketmq.client.producer.SendResult;

importorg.apache.rocketmq.spring.core.RocketMQTemplate;

importorg.springframework.messaging.Message;importorg.springframework.messaging.support.MessageBuilder;

importorg.springframework.stereotype.Service;

importjavax.annotation.Resource;

@Service

publicclassOrderService{

@Resource

privateRocketMQTemplate rocketMQTemplate;

// 定义Topic

privatestaticfinalStringORDER_SUCCESS_TOPIC="order_success_topic";

publicStringcreateOrder(Long userId,Long goodsId,Integer num){

// 1. 核心同步逻辑

String orderNo =generateOrderNo();

saveOrder(orderNo, userId, goodsId, num);

deductStock(goodsId, num);

// 2. 构建消息,发送到MQ(异步解耦)

OrderMsg msg =newOrderMsg(orderNo, userId);

Message<OrderMsg> message =MessageBuilder.withPayload(msg).build();

rocketMQTemplate.syncSend(ORDER_SUCCESS_TOPIC, message);

return"下单成功,订单号:"+ orderNo;

}

// 模拟方法省略

privateStringgenerateOrderNo(){return"ORD"+System.currentTimeMillis();}

privatevoidsaveOrder(String orderNo,Long userId,Long goodsId,Integer num){}

privatevoiddeductStock(Long goodsId,Integer num){}

// 消息实体

publicstaticclassOrderMsg{

privateString orderNo;

privateLong userId;

// 构造器、get/set

publicOrderMsg(String orderNo,Long userId){

this.orderNo = orderNo;

this.userId = userId;

}

publicStringgetOrderNo(){return orderNo;}

publicLonggetUserId(){return userId;}

}

}

2.2 消息消费者(独立服务 / 模块)

importorg.apache.rocketmq.spring.annotation.RocketMQMessageListener;

importorg.apache.rocketmq.spring.core.RocketMQListener;

importorg.springframework.stereotype.Service;

@Service

@RocketMQMessageListener(

topic ="order_success_topic",

consumerGroup ="order_success_consumer_group"

)

publicclassOrderConsumerimplementsRocketMQListener<OrderService.OrderMsg>{

@Override

publicvoidonMessage(OrderService.OrderMsg msg){

String orderNo = msg.getOrderNo();

Long userId = msg.getUserId();

// 异步执行所有附属业务

sendSms(userId, orderNo);

pushMessage(userId, orderNo);

recordAccountLog(orderNo);

addUserPoints(userId,10);

}

// 模拟业务方法

privatevoidsendSms(Long userId,String orderNo){}

privatevoidpushMessage(Long userId,String orderNo){}

privatevoidrecordAccountLog(String orderNo){}

privatevoidaddUserPoints(Long userId,Integer points){}}

}

3. 优缺点

  • 优点:解耦、削峰、异步、可靠;消息持久化,宕机不丢失,支持重试,适合高并发分布式系统;
  • 缺点:需要部署维护 MQ 中间件,架构复杂度更高。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、典型业务场景:订单下单后异步处理
    • 1. 业务背景
      • 原有同步方案问题
    • 2. 异步实现方案选型
  • 二、方案一:Spring @Async 异步(单体应用、简单场景)
    • 1. 前置配置
      • 1.1 开启异步注解
    • 2. 核心代码分层
      • 2.1 订单主服务(同步核心流程)
    • 3. 执行流程
    • 4. 优缺点
  • 三、方案二:消息队列异步(RocketMQ,分布式 / 高并发 / 企业级)
    • 1. 整体架构流程
    • 2. 核心代码(简化版)
      • 2.1 消息生产者(订单服务)
    • 3. 优缺点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档