[021-16].Redis实现秒杀优惠券功能

我的后端学习大纲

我的Redis学习大纲


1.全局ID生成器

1.1.订单表id说明:

  • 1.在大数据量的情况下,订单会越来越多,上千亿万条,不适合采用自增长类型
    在这里插入图片描述
  • 2.在如下的用户抢购场景中,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题:
    在这里插入图片描述
  • 1.id的规律性太明显
  • 2.受单表数据量的限制:
    • 每张表存储的数据量是有限的,那么单张表无法存储全部数据,就需要把数据存储到多张表中,但是如果存储到多张表时候,每个表的ID字段采用自增长类型,就会导致ID重复,但是订单ID是不可以重复的

1.2.什么是全局唯一ID:

  • 1.全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具
  • 2.全局唯一ID一般要满足下列特性:
    在这里插入图片描述

1.3.全局生成ID的特点:

  • 1.为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其它信息:
    在这里插入图片描述
  • 2.ID的组成部分(共64bit):
    • 符号位:1bit,永远为0
    • 时间戳:31bit,以秒为单位,可以使用69年
    • 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID

1.4.全局唯一ID生成策略:

a.策略举例:

  • UUID
  • Redis自增
  • snowflake算法
  • 数据库自增:单独一张表专门存储订单ID,然后订单表的ID都是来自于这个单独存储ID的表

b.Redis自增ID策略:

  • 每天一个key,方便统计订单量
  • ID构造是 时间戳 + 计数器

1.5.编码实现:

a.获取起始时间:

  • 1.获取时间戳,需要一个起始时间,在这里我们先获取一个起始时间的格式:
    在这里插入图片描述

b.


2.实现优惠券秒杀下单

1.1.优惠券介绍:

在这里插入图片描述

  • 1.表关系如下:
    • tb_voucher:优惠券的基本信息,优惠金额、使用规则等
    • tb_seckill_voucher:优惠券的库存、开始抢购时间,结束抢购时间。特价优惠券才需要填写这些信息

1.2.设置秒杀券:

a.说明:

  • 1.通畅我们通过管理页面,发布一些秒杀券和普通券来进行引流,这里我们通过postman来实现秒杀券的发布,未实现前端管理页的开发:

b.编码实现:

  • 1.controller层实现:
    在这里插入图片描述
  • 2.service层实现:
    在这里插入图片描述

1.3.实现客户端的秒杀功能:

a.功能说明:

  • 1.下单优惠券时需要判断两点:
    • 秒杀是否开始或结束,如果尚未开始或已经结束则无法下单
    • 库存是否充足,不足则无法下单
      在这里插入图片描述
  • 2.接口说明:
    在这里插入图片描述

b.编码实现:

在这里插入图片描述


3.超卖问题:

3.1.高并发情况说明

  • 1.对于秒杀功能,一般都是会发生并发的情况,无数的用户一起抢购优惠券,所以需要对高并发这种情况进行处理:

3.2.模拟高并发情况:

  • 对于高并发的情况的模拟,我们一般是使用Jmeter工具:
    在这里插入图片描述
    在这里插入图片描述

3.3.超卖现象分析:

在这里插入图片描述

3.4.加锁方式解决超卖问题:

a.悲观锁

  • 1.认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。
  • 2.例如Synchronized、Lock都属于悲观锁

b.乐观锁:

  • 1.认为线程安全问题不一定会发生,因此不加锁,只是在更新数据时去判断有没有其它线程对数据做了修改。
    • 如果没有修改则认为是安全的,自己才更新数据。
    • 如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常。

c.乐观锁实现方式:

c1.方法1:版本号法:

在这里插入图片描述

c2.CAS方案:在做更改动作的时候,判断条件和一开始查询出的库存值是否相同:

在这里插入图片描述

c3.编码实现乐观锁:
c4.乐观锁弊端:
  • 1.比如当有100个线程对同一个数据更改的时候,当有一条更改成功后,另外的99条线程都会失败,导致了失败率大大提高。虽然没有超卖,但是呢,效率却降低了跟多
c5.库存乐观锁弊端的改善:
  • 2.在乐观锁弊端问题中改善低效率有很多办法,在库存问题中,最佳的改善方法就是在更新库存的条件中,把更新的库存数量条件改为大于0
    在这里插入图片描述

4.一人一单:

4.1.需求说明:

  • 1.需求:修改秒杀业务,要求同一个优惠券,一个用户只能下一单
    在这里插入图片描述

4.2.添加查询是否已经购买过的逻辑:

  • 1.先添加查询购买与否的逻辑:
    在这里插入图片描述
  • 2.在多线程情况下,上述查询可能存在多个线程同时查询到未购买过的情况,然后就产生了多条记录插入到表中,因为知识查询的功能,未涉及到修改问题,所以需要添加悲观锁来解决
    在这里插入图片描述

3.5.集群模式下的超卖问题:

a.说明:

  • 1.通过加锁可以解决在单机情况下的一人一单安全问题,但是在集群模式下就不行了。我们将服务启动两份,端口分别为8081和8082

b.模拟集群:

在这里插入图片描述
在这里插入图片描述

c.修改nginx配置:

  • 1.修改nginx的conf目录下的nginx.conf文件,配置反向代理和负载均衡:
    在这里插入图片描述
  • 2.现在,用户请求会在这两个节点上负载均衡,再次测试下是否存在线程安全问题
    在这里插入图片描述

d.在集群或者分布式环境下,就会有多个JVM出现。所以出现了跨JVM

在这里插入图片描述


5.分布式锁

5.1.分布式锁介绍:

5.4.分布式锁设置:

在这里插入图片描述

16.6.Redis优化秒杀

16.7.Redis消息队列实现异步秒杀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值