加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

打造一款抢全网红包现金券脚本!抢了两万个红包!Python也能实现

发布时间:2020-12-17 00:53:54 所属栏目:Python 来源:网络整理
导读:概述 电商的秒杀、抢购,春运抢票,微信QQ抢红包,从技术的角度来说,这对于Web 系统是一个很大的考验. 高并发场景下,系统的优化和稳定是至关重要的. 互联网的开发包括? Java 后台、 NoSQL、数据库、限流、CDN、负载均衡 等内容,目前并没有权威性的技术和设

概述

电商的秒杀、抢购,春运抢票,微信QQ抢红包,从技术的角度来说,这对于Web 系统是一个很大的考验. 高并发场景下,系统的优化和稳定是至关重要的.

互联网的开发包括?Java 后台、 NoSQL、数据库、限流、CDN、负载均衡等内容,目前并没有权威性的技术和设计,有的只是长期经验的总结,但是使用这些经验可以有效优化系统,提高系统的并发能力.

进群:548377875 ? 即可获取数十套PDF哦!

我们接下来的几篇博文主要讨论 Java 后台、 NoSQL ( Redis )和数据库部分技术.


抢红包案例

主要分以下几大部分:

  1. 环境搭建
  2. 模拟超量发送的场景-DataBase(MySql5.7)
  3. 悲观锁的实现版本-DataBase(MySql5.7)
  4. 乐观锁的实现版本-DataBase(MySql5.7)
  5. Redis实现抢红包

案例关注点

模拟 20 万元的红包,共分为 2 万个可抢的小红包,有 3 万人同时抢夺的场景 ,模拟出现超发和如何保证数据一致性的问题。

在高并发的场景下,除了数据的一致性外,还要关注性能的问题 , 因为一般而言 , 时间太长用户体验就会很差,所以要测试数据一致性系统的性能?。


工程结构


库表设计

MySql5.7

/*==============================================================*/
/* Table: 红包表 */
/*==============================================================*/
create table T_RED_PACKET
(
 id int(12) not null auto_increment COMMENT '红包编号',user_id int(12) not null COMMENT '发红包的用户id',amount decimal(16,2) not null COMMENT '红包金额',send_date timestamp not null DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '发红包日期',total int(12) not null COMMENT '红包总数',unit_amount decimal(12) not null COMMENT '单个红包的金额',stock int(12) not null COMMENT '红包剩余个数',version int(12) default 0 not null COMMENT '版本(为后续扩展用)',note varchar(256) null COMMENT '备注',primary key clustered (id)
);

红包表表示存放红包的是一个大红包的信息,它会分为若干个小红包,为了业务简单,假设每一个红包是等额的。而对于抢红包而言,就是从大红包中抢夺那些剩余的小红包,剩余红包数会被记录在红包表中。 两个表有外键关联 T_RED_PACKET.id = T_USER_RED_PACKET.red_packet_id

/*==============================================================*/
/* Table: 用户抢红包表 */
/*==============================================================*/
create table T_USER_RED_PACKET 
(
 id int(12) not null auto_increment COMMENT '用户抢到的红包id',red_packet_id int(12) not null COMMENT '红包id',user_id int(12) not null COMMENT '抢红包用户的id',2) not null COMMENT '抢到的红包金额',grab_time timestamp not null DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '抢红包时间',primary key clustered (id)
);

/**

  • 插入一个20万元金额,2万个小红包,每个10元的红包数据
    */
    insert into T_RED_PACKET(user_id,amount,send_date,total,unit_amount,stock,note)
    values(1,200000.00,now(),20000,10.00,'20万元金额,2万个小红包,每个10元');
    commit;

这样就建好了两个表,并且将一个 20 万元金额,2 万个小红包,每个 10 元的红包信息插入到了红包表中,用作模拟数据。


Domain

有了这两个表,我们就可以为这两个表建两个 POJO 了,让这两个表和 POJO 对应起来,这两个 POJO 为 RedPacket 和 UserRedPacket,实现类序列化接口。

红包信息

package com.artisan.redpacket.pojo;
import java.io.Serializable;
import java.sql.Timestamp;
/**
 * 
 * 
 * @ClassName: RedPacket
 * 
 * @Description: 红包表对应的实体类,可序列化
 * 
 * @author: Mr.Yang
 * 
 * @date: 2018年10月8日 下午3:42:58
 */
public class RedPacket implements Serializable {
    private static final long serialVersionUID = 9036484563091364939L;
    // 红包编号
    private Long id;
    // 发红包的用户id
    private Long userId;
    // 红包金额
    private Double amount;
    // 发红包日期
    private Timestamp sendDate;
    // 红包总数
    private Integer total;
    // 单个红包的金额
    private Double unitAmount;
    // 红包剩余个数
    private Integer stock;
    // 版本(为后续扩展用)
    private Integer version;
    // 备注
    private String note;
    // 省略set/get
}

抢红包信息

package com.artisan.redpacket.pojo;
import java.io.Serializable;
import java.sql.Timestamp;
/**
 * 
 * 
 * @ClassName: UserRedPacket
 * 
 * @Description: 用户抢红包表
 * 
 * @author: Mr.Yang
 * 
 * @date: 2018年10月8日 下午3:47:40
 */
public class UserRedPacket implements Serializable {
    private static final long serialVersionUID = 7049215937937620886L;
    // 用户红包id
    private Long id;
    // 红包id
    private Long redPacketId;
    // 抢红包的用户的id
    private Long userId;
    // 抢红包金额
    private Double amount;
    // 抢红包时间
    private Timestamp grabTime;
    // 备注
    private String note;
    // 省略set/get
}

Dao层实现

MyBatis Dao接口类及对应的Mapper文件

使用 MyBatis 开发,先来完成大红包信息的查询先来定义一个 DAO 对象

package com.artisan.redpacket.dao;

import org.springframework.stereotype.Repository;

import com.artisan.redpacket.pojo.RedPacket;

@Repository

public interface RedPacketDao {

/**

* 获取红包信息.

* @param id --红包id

* @return 红包具体信息

*/

public RedPacket getRedPacket(Long id);

/**

* 扣减抢红包数.

* @param id -- 红包id

* @return 更新记录条数

*/

public int decreaseRedPacket(Long id);

}

其中的两个方法 , 一个是查询红包,另一个是扣减红包库存。

抢红包的逻辑是,先查询红包的信息,看其是否拥有存量可以扣减。如果有存量,那么可以扣减它,否则就不扣减。

接着将对应的Mapper映射文件编写一下



    
    推荐文章
      热点阅读