# 《Seckill秒杀系统》第56章:异步化下单编码实现

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★★☆☆
  • 本章重点:重点理解并掌握异步化下单的编码实现,实现同步下单流程与异步下单流程无缝切换的编码实现,掌握在异步化下单流程中的下单许可的编码实现。

大家好,我是冰河~~

在前面的文章中,我们一起实现了异步化下单的流程设计,在异步化流程设计中,引入了下单许可的概念,并对下单许可的设计进行了详细的描述。可以这么说,异步化设计是提升高并发系统吞吐量必不可少的一种设计方式。

# 一、前言

异步化设计是提升高并发系统吞吐量必不可少的一种设计方式,当一个系统引入异步化设计时,上游服务的操作不必等下游服务响应后再返回。上游服务将请求发送到消息队列后,即可返回。继续承接其他的请求流量,这样就提升了系统的吞吐量和并发量。所以,高并发系统多多少少都会支持异步化设计,所以,对我们的秒杀系统来说,下单流程的一个优化点就是支持异步化设计和下单许可设计。

# 二、本章诉求

对下单流程进行扩展,在原有同步下单流程的基础上,扩展异步化下单流程,考虑到尽量让一些有效流量进入下单流程,在异步化设计的基础上引入下单许可设计。下单许可就是在原有秒杀商品库存的基础上,按照一定的比例来设置真正进入下单流程的流量,保证秒杀商品不会超卖也不会少卖。可以这么说,下单许可,在一定程度上也是保证秒杀系统核心链路稳定性的有效手段。

本章,就对秒杀系统下单流程的异步化和下单许可进行编码实现。

# 三、扩展原有下单流程

本节,主要是修改原有的下单逻辑,在原有下单流程的基础上,扩展成同时支持同步下单和异步下单的逻辑,具体扩展步骤如下所示。

(1)新增SeckillSubmitOrderService接口

新增一个SeckillSubmitOrderService接口,主要是将提交订单的逻辑从原有的SeckillOrderService接口中分离出来,单独放到SeckillSubmitOrderService接口,SeckillSubmitOrderService接口的实现类会分成同步下单和异步下单两个实现类。

SeckillSubmitOrderService接口的源码详见:seckill-order-application工程下的io.binghe.seckill.order.application.service.SeckillSubmitOrderService。

public interface SeckillSubmitOrderService {
    SeckillOrderSubmitDTO saveSeckillOrder(Long userId, SeckillOrderCommand seckillOrderCommand);
    default void handlePlaceOrderTask(SeckillOrderTask seckillOrderTask){}
    default void checkSeckillOrder(Long userId, SeckillOrderCommand seckillOrderCommand){}
}
1
2
3
4
5

可以看到,在SeckillSubmitOrderService接口中提供了一个保存订单的saveSeckillOrder()方法,提供了一个处理订单任务的handlePlaceOrderTask()默认方法和检查订单数据有效性的checkSeckillOrder()默认方法。

其中,当执行异步化下单时,订单服务监听到下单任务时,会调用handlePlaceOrderTask()方法来执行下单的业务逻辑。checkSeckillOrder()方法是在提交订单前执行的数据校验操作。saveSeckillOrder()方法无论是同步下单还是异步下单,都会实现这个保存订单的方法。

(2)新增SeckillBaseSubmitOrderServiceImpl类

为了抽象出同步与异步下单流程执行的相同逻辑,我们会创建一个提交订单的父级抽象类SeckillBaseSubmitOrderServiceImpl,将检测订单数据的方法在SeckillBaseSubmitOrderServiceImpl类中进行实现。

SeckillBaseSubmitOrderServiceImpl类的源码详见:seckill-order-application工程下的io.binghe.seckill.order.application.service.impl.SeckillBaseSubmitOrderServiceImpl。

@Override
public void checkSeckillOrder(Long userId, SeckillOrderCommand seckillOrderCommand) {
    if (userId == null || seckillOrderCommand == null){
        throw new SeckillException(ErrorCode.PARAMS_INVALID);
    }
    //模拟风控
    if (!securityService.securityPolicy(userId)){
        throw new SeckillException(ErrorCode.USER_INVALID);
    }
    //获取商品信息
    SeckillGoodsDTO seckillGoods = seckillGoodsDubboService.getSeckillGoods(seckillOrderCommand.getGoodsId(), seckillOrderCommand.getVersion());
    //检测商品信息
    seckillPlaceOrderService.checkSeckillGoods(seckillOrderCommand, seckillGoods);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 查看完整文章

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码