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

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

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

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

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

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

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


抢红包案例

主要分以下几大部分:

环境搭建 模拟超量发送的场景-DataBase(MysqL5.7) 悲观锁的实现版本-DataBase(MysqL5.7) 乐观锁的实现版本-DataBase(MysqL5.7) 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_REDPACKET(userID,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映射文件编写一下