美文网首页
秒杀系统之二:接口限流(令牌桶和漏斗算法)

秒杀系统之二:接口限流(令牌桶和漏斗算法)

作者: 徒手說梦话 | 来源:发表于2020-09-30 14:35 被阅读0次

3. 接口限流

限流:是对某一时间窗口内的请求数进行限制,保持系统的可用性和稳定性,防止因流量暴增而导致的系统运行缓慢或宕机

3.1 接口限流

在面临高并发的抢购请求时,我们如果不对接口进行限流,可能会对后台系统造成极大的压力。大量的请求抢购成功时需要调用下单的接口,过多的请求打到数据库会对系统的稳定性造成影响。

3.2 如何解决接口限流

常用的限流算法有令牌桶和和漏桶(漏斗算法),而Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法。在开发高并发系统时有三把利器用来保护系统:缓存降级限流

  • 缓存:缓存的目的是提升系统访问速度和增大系统处理容量
  • 降级:降级是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行
  • 限流:限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。

3.3 令牌桶和漏斗算法

image-20200401091230233.png
  • 漏斗算法:漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
  • 令牌桶算法:最初来源于计算机网络。在网络传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送。令牌桶算法就实现了这个功能,可控制发送到网络上数据的数目,并允许突发数据的发送。大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小。这意味,面对瞬时大流量,该算法可以在短时间内请求拿到大量令牌,而且拿令牌的过程并不是消耗很大的事情。

3.4 令牌桶简单使用

1. 项目中引入依赖
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>
2. 令牌桶算法的基本使用
public class StockController {
    @Autowired
    private OrderService orderService;

    //创建令牌桶实例
    private RateLimiter rateLimiter =  RateLimiter.create(40);

    @GetMapping("sale")
    public String sale(Integer id){
        //1.没有获取到token请求一直知道获取到token 令牌
        //log.info("等待的时间: "+  rateLimiter.acquire());

        //2.设置一个等待时间,如果在等待的时间内获取到了token 令牌,则处理业务,如果在等待时间内没有获取到响应token则抛弃
        if(!rateLimiter.tryAcquire(2, TimeUnit.SECONDS)){
            System.out.println("当前请求被限流,直接抛弃,无法调用后续秒杀逻辑....");
            return "抢购失败!";
        }
        System.out.println("处理业务.....................");
        return "抢购成功";
    }
}

3.5使用令牌桶算法实现乐观锁+限流

1. 使用令牌桶改造controller实现乐观锁+限流
 //开发一个秒杀方法 乐观锁防止超卖+ 令牌桶算法限流
    @GetMapping("killtoken")
    public String killtoken(Integer id){
        System.out.println("秒杀商品的id = " + id);
        //加入令牌桶的限流措施
        if(!rateLimiter.tryAcquire(3, TimeUnit.SECONDS)){
            log.info("抛弃请求: 抢购失败,当前秒杀活动过于火爆,请重试");
            return "抢购失败,当前秒杀活动过于火爆,请重试!";
        }
        try {
            //根据秒杀商品id 去调用秒杀业务
            int orderId = orderService.kill(id);
            return "秒杀成功,订单id为: " + String.valueOf(orderId);
        }catch (Exception e){
            e.printStackTrace();
            return e.getMessage();
        }
    }

相关文章

  • 秒杀系统之二:接口限流(令牌桶和漏斗算法)

    3. 接口限流 限流:是对某一时间窗口内的请求数进行限制,保持系统的可用性和稳定性,防止因流量暴增而导致的系统运行...

  • (9)弹力设计篇之“限流设计”

    1、限流的策略 2、限流的算法:计数器、队列、漏斗和令牌桶。 3、如何基于响应时间来限流。 4、限流设计的要点 限...

  • 基础架构 | 限流算法

    限流算法 令牌桶算法 漏桶算法

  • Guava-RateLimiter详解

    常用的限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶...

  • 限流算法

    限流的算法 常见的限流算法有:计数器、漏桶和令牌桶算法。 计数器 设定单位时间限制接口的请求数量为n,单位时间内的...

  • Nginx 限流配置(转)

    限流算法: 1. 令牌桶算法 算法思想是: 令牌以固定速率产生,并缓存到令牌桶中;令牌桶放满时,多余的令牌被丢弃;...

  • Nginx限流配置(转载)

    1、限流算法 令牌桶算法 算法思想是:a、令牌以固定速率产生,并缓存到令牌桶中;b、令牌桶放满时,多余的令牌被丢弃...

  • Zuul 网关限流---Guava RateLimiter

    限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法也就是以固定的频率向桶中放入令...

  • Redis+Lua脚本三步实现分布式系统限流

      在分布式系统中,说到限流方案我们一般会使用redis结合限流算法来做,一般的限流算法有令牌桶算法、漏桶算法、固...

  • 漏桶算法与令牌桶算法的区别

    令牌桶算法是通过控制令牌生成的速度进行限流,漏桶算法是控制请求从桶中流出的速度进行限流。简单理解为:令牌桶控制进,...

网友评论

      本文标题:秒杀系统之二:接口限流(令牌桶和漏斗算法)

      本文链接:https://www.haomeiwen.com/subject/exwuuktx.html