流量削峰

浪涌洪峰流量。第一秒流量涌入的问题。使用平滑的方式过度掉,使系统性能平滑提升。

 

普通的下单:

  • 下单接口会被脚本不停刷,脚本会比用户手速快
  • 秒杀验证逻辑和秒杀下单接口强关联,代码冗余度高

 

秒杀令牌

  • 秒杀接口需要依靠令牌才能进入
  • 令牌由秒杀活动产生
  • 秒杀活动对令牌管理
  • 秒杀下单前需要先让用户获得令牌

提供一个令牌接口,用户下单前,调用这个接口,生成了令牌后,存入redis。

下单的时候再判断令牌是否在redis里。

缺点:没有做数量限制

令牌相关的

  1. 这个大闸是其中一种做法
    1. 令牌存放的表 xx_token
    2. id、日期、业务号、令牌余量(大闸)、时间
    3. 这样用表的好处是可以实时查看。
    4. update sk_token
      set `count` = if (`count` < #{decreaseCount}, 0, `count` - #{decreaseCount})
      where `date` = #{date}
      and train_code = #{trainCode}
      and `count` > 0
  2. 令牌也可以放到内存中使用。

令牌的初始化

  初始化车次的时候就初始化令牌信息。

 

 

秒杀大闸

基于秒杀令牌的原理,控制令牌的发放数量。

一般是有多少库存,就比库存多发放一点点。 这个数在保存库存的时候存。

库存售罄也前置到这里。

 

每次发放令牌之后,大闸数量-1,小于0之后,不再发放。

 

缺点:

如果库存大,还是无法一瞬间拦截大量请求,而且商品的种类也多,大闸就种类也多。

 

队列泄洪

使用队列

队列减少上下问切换,减少资源竞争锁的浪费。

依靠排队和校友拥塞窗口程度调整队列释放流量大小

支付宝的银行网关队列,就是用队列的。

 

ExecutorService executorService; 

@PostConstruct

public void init(){

  //只有20个线程的线程池

  executorService = Executor.newFixedThreadPool(20);

 

}

 

Future f = executorService.submit(new Callable){

  下单。

  减库存。

}

 

f.get();

这样 同一时间 只有20个线程被执行  队列化泄洪。

这个只是简单的一种方式,本地的一种实现。多台机器就会有多个线程池来实现泄洪。

 

所以本地和分布式都有,本地实现效率还是高。负载有可能不均衡。

 正常用分布式,降级时为本地。是一种实现方案。

posted @ 2023-06-10 17:11  CodingOneTheWay  阅读(54)  评论(0编辑  收藏  举报
回到顶部