zoukankan      html  css  js  c++  java
  • 秒杀活动的高并发问题和超卖问题的解决方案

    看到这类秒杀,估计很多开发者都头疼,因为你很少真真能在项目接触到,不过没关系,该了解的我们也要了解,

    高并发和超卖是秒杀活动中常见的2个问题,也是需要面临解决的问题

    1. 高并发:比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验;
    2. 超卖:任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难题;

    问题:如何解决此问题?

    答:前端三板斧(扩容、限流、静态化),后端两条路(内存加排队)

    1. 前端:

      扩容:加机器,这是最简单的方法,通过增加前端池的整体承载量来扛峰值。
      限流:一般都会采用IP级别的限流,即针对某一个IP限制单位时间内发起的请求数量,或者活动入口的时候增加游戏或者问问题环节进行销峰操作。
      静态化:将活动页面中所有的可静态化元素全部静态化,并尽量减少动态元素,通过CNN(加速服务器)来扛峰值。

    2. 后端:

      内存:将库存从MySQL前移到Redis中,所有的读写操作放到内存中,由于Redis中没有锁,所以不会存在相互等待,并且Redis的读写性能都远高于MySQL,这就解决了性能问题。
      排队:引入队列,然后将所有写DB操作在单队列中排队,完全串行处理。当达到库存阀值的时候就不在消费队列,并关闭购买功能。这就解决了超卖问题。

    超卖具体的实现方法: 比如我们的商品表 goods  , 对应的字段  num  表示当前库存

    方法一:mysql 排它锁原理

    通过mysql 语句 update goods set num = num - 1 WHERE id = 1001 and num > 0;

    假设现在商品只剩下一件了,此时数据库中 num = 1;
    但有100个线程同时读取到了这个 num = 1,所以100个线程都开始减库存了。
    但最终结果,只有一个线程减库存成功,其他99个线程全部失败。
    为何?
    这就是MySQL中的排他锁起了作用。
    排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
    就是类似于我在执行update操作的时候,这一行是一个事务(默认加了排他锁)。这一行不能被任何其他线程修改和读写。

    方法二:cas原理

    select version from goods WHERE id= 1001
    update goods set num = num - 1, version = version + 1 WHERE id= 1001 AND num > 0 AND version = @version(上面查到的version);

    这种方式采用了版本号的方式,其实也就是CAS的原理。
    假设此时version = 100, num = 1; 100个线程进入到了这里,同时他们select出来版本号都是version = 100。
    然后直接update的时候,只有其中一个先update了,同时更新了版本号。
    那么其他99个在更新的时候,会发觉version并不等于上次select的version,就说明version被其他线程修改过了。那么放弃这次update

    方法三:redis 单线程方法

    利用redis的单线程预减库存。比如商品有100件。那么我在redis存储一个k,v。例如 <gs_1001, 100>
    每一个用户线程进来,key值就减1,等减到0的时候,全部拒绝剩下的请求。
    那么也就是只有100个线程会进入到后续操作。所以一定不会出现超卖的现象。

  • 相关阅读:
    inotify和rsync实现数据实时同步
    Powershell在相应的文件夹下用管理员模式打开
    LOJ6498「雅礼集训 2018 Day2」农民
    LOJ6502「雅礼集训 2018 Day4」Divide
    LOJ6501「雅礼集训 2018 Day4」Cube
    2021-10-11 杂题选听
    LOJ6507 「雅礼集训 2018 Day7」A
    LOJ6497「雅礼集训 2018 Day1」图
    CF103E Buying Sets
    CF266D BerDonalds(图的绝对中心)
  • 原文地址:https://www.cnblogs.com/fangdada/p/15059851.html
Copyright © 2011-2022 走看看