springboot+websocket实现并发抢红包功能

概述

抢红包功能作为几大高并发场景中典型,应该如何实现?

源码地址:gitee.com/tech-famer/…

分析

参考微信抢红包功能,将抢红包分成一下几个步骤:

  1. 发红包;主要填写红包信息,生成红包记录
  2. 红包支付回调;用户发红包支付成功后,收到微信支付付款成功的回调,生成指定数量的红包。
  3. 抢红包;用户并发抢红包。
  4. 拆红包;记录用户抢红包记录,转账抢到的红包金额。

效果展示

项目使用sessionId模拟用户,示例打开俩个浏览器窗口模拟两个用户。

20211124_110334.gif

设计开发

表结构设计

红包记录在 redpacket 表中,用户领取红包详情记录在 redpacket_detail 表中。

CREATE DATABASE  `redpacket`;

use `redpacket`;

CREATE TABLE `redpacket`.`redpacket` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `packet_no` varchar(32) NOT NULL COMMENT '订单号',
  `amount` decimal(5,2) NOT NULL COMMENT '红包金额最高10000.00元',
  `num` int(11) NOT NULL COMMENT '红包数量',
  `order_status` int(4) NOT NULL DEFAULT '0' COMMENT '订单状态:0初始、1待支付、2支付成功、3取消',
  `pay_seq` varchar(32) DEFAULT NULL COMMENT '支付流水号',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `user_id` varchar(32) NOT NULL COMMENT '用户ID',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `pay_time` datetime DEFAULT NULL COMMENT '支付时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='红包订单表';

CREATE TABLE `redpacket`.`redpacket_detail` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `packet_id` bigint(20) NOT NULL COMMENT '红包ID',
  `amount` decimal(5,2) NOT NULL COMMENT '红包金额',
  `received` int(1) NOT NULL DEFAULT '0' COMMENT '是否领取0未领取、1已领取',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `user_id` varchar(32) DEFAULT NULL COMMENT '领取用户',
  `packet_no` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='红包详情表';

复制代码

发红包设计

用户需要填写红包金额、红包数量、备注信息等,生成红包记录,微信收银台下单,返回用户支付。

public RedPacket generateRedPacket(ReqSendRedPacketsVO data,String userId) {
    final BigDecimal amount = data.getAmount();
    //红包数量
    final Integer num = data.getNum();

    //初始化订单
    final RedPacket redPacket = new RedPacket();
    redPacket.setPacketNo(UUID.randomUUID().toString().replace("-", ""));
    redPacket.setAmount(amount);
    redPacket.setNum(num);
    redPacket.setUserId(userId);
    Date now = new Date();
    redPacket.setCreateTime(now);
    redPacket.setUpdateTime(now);
    int i = redPacketMapper.insertSelective(redPacket);
    if (i != 1) {
        throw new ServiceException("生成红包出错", ExceptionType.SYS_ERR);
    }

    //模拟收银台下单
    String paySeq = UUID.randomUUID().toString().replace("-", "");

    //拿到收银台下单结果,更新订单为待支付状态
    redPacket.setOrderStatus(1);//待支付
    redPacket.setPaySeq(paySeq);
    i = redPacketMapper.updateByPrimaryKeySelective(redPacket);
    if (i
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值