SpringBoot+RabbitMQ+Redis实现商品秒杀

业务分析

一般而言,商品秒杀大概可以拆分成以下几步:

  1. 用户校验
    校验是否多次抢单,保证每个商品每个用户只能秒杀一次
  2. 下单
    订单信息进入消息队列,等待消费
  3. 减少库存
    消费订单消息,减少商品库存,增加订单记录
  4. 付款
    十五分钟内完成支付,修改支付状态

创建表

goods_info 商品库存表
说明
id 主键(uuid)
goods_name 商品名称
goods_stock 商品库存
package com.jason.seckill.order.entity;

/**
 * 商品库存
 */

public class GoodsInfo {
   
   

    private String id;
    private String goodsName;
    private String goodsStock;

    public String getId() {
   
   
        return id;
    }

    public void setId(String id) {
   
   
        this.id = id;
    }

    public String getGoodsName() {
   
   
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
   
   
        this.goodsName = goodsName;
    }

    public String getGoodsStock() {
   
   
        return goodsStock;
    }

    public void setGoodsStock(String goodsStock) {
   
   
        this.goodsStock = goodsStock;
    }

    @Override
    public String toString() {
   
   
        return "GoodsInfo{" +
                "id='" + id + '\'' +
                ", goodsName='" + goodsName + '\'' +
                ", goodsStock='" + goodsStock + '\'' +
                '}';
    }
}

order_info 订单记录表
说明
id 主键(uuid)
user_id 用户id
goods_id 商品id
pay_status 支付状态(0-超时未支付 1-已支付 2-待支付)
package com.jason.seckill.order.entity;

/**
 * 下单记录
 */
public class OrderRecord {
   
   

    private String id;
    private String userId;
    private String goodsId;
    /**
     * 0-超时未支付  1-已支付  2-待支付
     */
    private Integer payStatus;

    public String getId() {
   
   
        return id;
    }

    public void setId(String id) {
   
   
        this.id = id;
    }

    public String getUserId() {
   
   
        return userId;
    }

    public void setUserId(String userId) {
   
   
        this.userId = userId;
    }

    public String getGoodsId() {
   
   
        return goodsId;
    }

    public void setGoodsId(String goodsId) {
   
   
        this.goodsId = goodsId;
    }

    public Integer getPayStatus() {
   
   
        return payStatus;
    }

    public void setPayStatus(Integer payStatus) {
   
   
        this.payStatus = payStatus;
    }

    @Override
    public String toString() {
   
   
        return "OrderRecord{" +
                "id='" + id + '\'' +
                ", userId='" + userId + '\'' +
                ", goodsId='" + goodsId + '\'' +
                '}';
    }
}

功能实现

1.用户校验

使用redis做用户校验,保证每个用户每个商品只能抢一次,上代码:

public boolean checkSeckillUser(OrderRequest order) {
   
   
        String key = env.getProperty("seckill.redis.key.prefix") + order.getUserId() + order.getGoodsId();
        return redisTemplate.opsForValue().setIfAbsent(key,"1");
    }

userId+orderId的组合作为key,利用redis的setnx分布式锁原理来实现。如果是限时秒杀,可以通过设置key的过期时间来实现。

2.下单

下单信息肯定是要先扔到消息队列里的,这里采用RabbitMQ来做消息队列,先来看一下消息队列的模型图:
订单消息队列
rabbitmq的配置:

#rabbitmq配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#消费者数量
spring.rabbitmq.listener.simple.concurrency=5
#最大消费者数量
spring.rabbitmq.listener.simple.max-concurrency=10
#消费者每次从队列获取的消息数量。写多了,如果长时间得不到消费,数据就一直得不到处理
spring.rabbitmq.listener.simple.prefetch=1
#消费接收确认机制-手动确认
spring.rabbitmq.listener.simple.acknowledge-mode=manual

mq.env=local
#订单处理队列
#交换机名称
order.mq.exchange
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值