天天看点

RabbitMq实现流量削峰,抢红包实例

环境:springboot+maven+jdk1.8+mybatis+rabbitMq

开发工具:idea

本文默认已安装rabbitMq,未安装可参考博主之前的博客进行安装。。

首先创建表:

CREATE TABLE tb_redpack(
   id int not null AUTO_INCREMENT,
     userId varchar(32) not null comment '发红包用户',
     amount decimal(10,2) not null comment '红包金额',
     unitAmount decimal(10,2) not null comment '单个红包金额',
     total int not null comment '红包个数',
     remain int not null comment '红包剩余个数',
     sendDate datetime not null comment '发红包时间',
     version int default 0 not null comment '版本控制,扩展乐观锁使用',
     primary key(id)
);

INSERT INTO tb_redpack(userId,amount,unitAmount,total,remain,sendDate)
VALUES("999999",100000.00,100.00,1000,1000,now());

CREATE TABLE tb_user_redpack(
  id int not null AUTO_INCREMENT,
  userId varchar(32) not null comment '抢红包用户',
  redpackId int not null comment '发红包记录id',
  amount decimal(10,2) not null comment '抢的红包金额',
  grabDate datetime not null comment '抢红包时间',
  version int default 0 not null comment '版本控制,扩展乐观锁使用',
  primary key(id)
);      

实体类

package com.sc.entity;

import java.math.BigDecimal;
import java.util.Date;

public class UserRedpack {
    /**
     * 
     */
    private Integer id;

    /**
     * 抢红包用户
     */
    private String userid;

    /**
     * 发红包记录id
     */
    private Integer redpackid;

    /**
     * 抢的红包金额
     */
    private BigDecimal amount;

    /**
     * 抢红包时间
     */
    private Date grabdate;

    /**
     * 版本控制,扩展乐观锁使用
     */
    private Integer version;

    /**
     * 
     * @return id 
     */
    public Integer getId() {
        return id;
    }

    /**
     * 
     * @param id 
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 抢红包用户
     * @return userId 抢红包用户
     */
    public String getUserid() {
        return userid;
    }

    /**
     * 抢红包用户
     * @param userid 抢红包用户
     */
    public void setUserid(String userid) {
        this.userid = userid == null ? null : userid.trim();
    }

    /**
     * 发红包记录id
     * @return redpackId 发红包记录id
     */
    public Integer getRedpackid() {
        return redpackid;
    }

    /**
     * 发红包记录id
     * @param redpackid 发红包记录id
     */
    public void setRedpackid(Integer redpackid) {
        this.redpackid = redpackid;
    }

    /**
     * 抢的红包金额
     * @return amount 抢的红包金额
     */
    public BigDecimal getAmount() {
        return amount;
    }

    /**
     * 抢的红包金额
     * @param amount 抢的红包金额
     */
    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    /**
     * 抢红包时间
     * @return grabDate 抢红包时间
     */
    public Date getGrabdate() {
        return grabdate;
    }

    /**
     * 抢红包时间
     * @param grabdate 抢红包时间
     */
    public void setGrabdate(Date grabdate) {
        this.grabdate = grabdate;
    }

    /**
     * 版本控制,扩展乐观锁使用
     * @return version 版本控制,扩展乐观锁使用
     */
    public Integer getVersion() {
        return version;
    }

    /**
     * 版本控制,扩展乐观锁使用
     * @param version 版本控制,扩展乐观锁使用
     */
    public void setVersion(Integer version) {
        this.version = version;
    }
}      
package com.sc.entity;

import java.math.BigDecimal;
import java.util.Date;

public class Redpack {
    /**
     * 
     */
    private Integer id;

    /**
     * 发红包用户
     */
    private String userid;

    /**
     * 红包金额
     */
    private BigDecimal amount;

    /**
     * 单个红包金额
     */
    private BigDecimal unitamount;

    /**
     * 红包个数
     */
    private Integer total;

    /**
     * 红包剩余个数
     */
    private Integer remain;

    /**
     * 发红包时间
     */
    private Date senddate;

    /**
     * 版本控制,扩展乐观锁使用
     */
    private Integer version;

    /**
     * 
     * @return id 
     */
    public Integer getId() {
        return id;
    }

    /**
     * 
     * @param id 
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 发红包用户
     * @return userId 发红包用户
     */
    public String getUserid() {
        return userid;
    }

    /**
     * 发红包用户
     * @param userid 发红包用户
     */
    public void setUserid(String userid) {
        this.userid = userid == null ? null : userid.trim();
    }

    /**
     * 红包金额
     * @return amount 红包金额
     */
    public BigDecimal getAmount() {
        return amount;
    }

    /**
     * 红包金额
     * @param amount 红包金额
     */
    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    /**
     * 单个红包金额
     * @return unitAmount 单个红包金额
     */
    public BigDecimal getUnitamount() {
        return unitamount;
    }

    /**
     * 单个红包金额
     * @param unitamount 单个红包金额
     */
    public void setUnitamount(BigDecimal unitamount) {
        this.unitamount = unitamount;
    }

    /**
     * 红包个数
     * @return total 红包个数
     */
    public Integer getTotal() {
        return total;
    }

    /**
     * 红包个数
     * @param total 红包个数
     */
    public void setTotal(Integer total) {
        this.total = total;
    }

    /**
     * 红包剩余个数
     * @return remain 红包剩余个数
     */
    public Integer getRemain() {
        return remain;
    }

    /**
     * 红包剩余个数
     * @param remain 红包剩余个数
     */
    public void setRemain(Integer remain) {
        this.remain = remain;
    }

    /**
     * 发红包时间
     * @return sendDate 发红包时间
     */
    public Date getSenddate() {
        return senddate;
    }

    /**
     * 发红包时间
     * @param senddate 发红包时间
     */
    public void setSenddate(Date senddate) {
        this.senddate = senddate;
    }

    /**
     * 版本控制,扩展乐观锁使用
     * @return version 版本控制,扩展乐观锁使用
     */
    public Integer getVersion() {
        return version;
    }

    /**
     * 版本控制,扩展乐观锁使用
     * @param version 版本控制,扩展乐观锁使用
     */
    public void setVersion(Integer version) {
        this.version = version;
    }
}      

业务逻辑主要就是:

1、用户抢红包,进入后台发送消息进入rabbitmq队列。

/**
   * 发送消息
   */
  public void sendGradRedPack(String userid) {
    try {
      rabbitTemplate.convertAndSend("info", userid);
    } catch (AmqpException e) {
      log.error("发送用户抢红包进入消息队列异常:"+e.getMessage());
      e.printStackTrace();
    }
  }      
public void grabRedPack(String userId) {
    try {
      //1.查询红包剩余个数是否大于0
      int remain = redpackService.getRedPackRemain(redpackId);
      if(remain > 0) {
        //2.扣减红包个数
        int result = redpackService.deducteRedPack(redpackId);
        if(result > 0) {
          //3.新增用户抢红包记录
          UserRedpack userRedpack = new UserRedpack();
          userRedpack.setUserid(userId);
          userRedpack.setRedpackid(redpackId);
          userRedpack.setGrabdate(new Date());
          userRedpack.setAmount(new BigDecimal(amount));
          userRedpackService.insertGradReadPack(userRedpack);
        }
        
      }
      //异步通知用户抢红包成功
    } catch (Exception e) {
      log.error("处理抢单异常:"+e.getMessage());
      throw new RuntimeException("处理抢单异常");
    }
  }