基于Redis的秒杀系统

在这里插入图片描述

一. 问题思考

  1. 如何防止链接暴露?
  2. 怎么防止恶意请求?
  3. 高并发可能带来的问题?
  4. 限流?降级?熔断?
  5. 如何防止超卖问题?

二. 问题解决与设计

  1. 链接设计

    1.前端将按钮置灰,前端定时请求后端服务器,获取最新的北京时间,到时间点才能点击。
    2.采用MD5加密算法对URL加密,将URL动态化,通过前端代码获取url后台校验才能通过。

    注:MD5加密算法原理
    1、数据填充
    对消息进行数据填充,使消息的长度对512取模得448,设消息长度为X,即满足X mod 512=448。根据此公式得出需要填充的数据长度。
    填充方法:在消息后面进行填充,填充第一位为1,其余为0。
    2、添加消息长度
    在第一步结果之后再填充上原消息的长度,可用来进行的存储长度为64位。如果消息长度大于264,则只使用其低64位的值,即(消息长度 对 264取模)。
    在此步骤进行完毕后,最终消息长度就是512的整数倍。
    3、数据处理
    准备需要用到的数据:

    4个常数: A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;
    4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z));  H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));
    

    把消息分以512位为一分组进行处理,每一个分组进行4轮变换,以上面所说4个常数为起始变量进行计算,重新输出4个变量,以这4个变量再进行下一分组的运算,如果已经是最后一个分组,则这4个变量为最后的结果,即MD5值。

  2. 高并发下的安全问题

    1.Redis集群,主从同步、读写分离
    2. Nginx进行负载均衡
    Nginx官方版本限制IP的连接和并发分别有两个模块:
    limit_req_zone: 用来限制单位时间内的请求数,即速率限制,采用的漏桶 算法。
    limit_req_conn: 用来限制同一时间连接数,即并发限制。
    3. 解决缓存击穿、缓存雪崩、缓存穿透
    解决方法:https://blog.csdn.net/qq_44837912/article/details/104425408
    4. 限流
    前端限流:点击按钮两下后间隔5秒才可以继续点击;
    后端限流:对于能够执行生成担当和支付等操作的用户,当产品售空时,后端return了一个false,前端直接秒杀结束,后端也关闭后续无效的请求。
    Tip:真正的限流还会有限流组件的加入例如:阿里的Sentinel、Hystrix等。

  3. 库存预热

    提前把商品的库存从MySQL中加载到Redis,当秒杀结束,再异步的去修改库存。

  4. 超卖现象

    Lua脚本是类似Redis事务,有一定的原子性,不会被其他命令插队,可以完成一些Redis事务性的操作。
    写一个脚本把判断库存扣减库存的操作都写在一个脚本丢给Redis去做,那到0了后面的都Return False了是吧,一个失败了你修改一个开关,直接挡住所有的请求,然后再做后面的事情嘛。

  5. 限流&降级&熔断&隔离

  • 功能简单实现

技术难点1:库存和用户购买记录的同步
每次请求时,都先去判断用户购买记录是否属于二次购买,如果是二次购买则抛出异常,即购买失败,否则去判断库存是否为0,若库存为0则购买失败,若库存不为0,则进行减库存操作,紧接着记录用户的购买记录,为了保证减库存和用户购买记录增加同步,故在同一个事务中进行减库存和用户购买记录增加的操作。

技术难点2:前端不断向后端发送获取时间、库存的请求。
考虑到频繁访问数据库可能会将数据库刷爆,故得使用一个缓存去存储时间、库存等信息,因为Redis的QPS能达到10W+,故使用Redis去扮演这样的一个缓存角色,事先将商品信息、时间、库存缓存到Redis中,即使前端不断发送请求也无需担心数据库被刷爆。

提升1:
由于每次对库存和用户购买记录的操作都需要在数据库中进行,在高并发情况下可能对秒杀有一定影响,故考虑到使用消息队列进行消峰处理,因为Redis是一个单线程的原子化操作,故减库存的操作在Redis中进行,而用户购买记录在消息队列中操作,等秒杀结束在异步地将数据同步到数据库中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值