简介

限流是保障服务稳定的一个方式(此篇文章以摘要参考文档为主)

方案

  • 信号量
  • 计数器
  • 滑动窗口
  • 漏桶算法
  • 令牌桶算法
  • 分布式限流

信号量

信号量实际上就是限制系统的并发量,来达到限流的目的。

实现方式与一把可以多次获取的锁非常相似。

计数器

比如限制1秒钟内请求数最多为10个,每当进来一个请求,则计数器+1。当计数器达到上限时,则触发限流。时间每经过1秒,则重置计数器

  • 主要问题
    • 第一秒的后半秒和第二秒的前半秒将限制数量用完,但此一秒内系统流量超过了单个一秒的限制
    • 一秒的前半秒将限制数量用完,则后半秒系统无法接受请求

滑动窗口

滑动窗口本质上是一种粒度更细的计数器,每次窗口滑动时,重置前100ms之间内的计数,而不是完整的1s

主要问题和计数器方案相同

漏桶

漏桶(Leaky Bucket)算法思路如下,请求先进入到漏桶里,漏桶以一定的速度放出请求给系统响应,当漏桶中无法接收更多的请求则丢弃,这样可以强行限制请求的处理速率

  • 主要问题
    • 处理速度固定,无法处理短时间内突发的超高请求

令牌桶

令牌桶算法思路如下,系统以固定的速率往令牌桶中放入令牌,请求进入时,从桶中取走令牌,当桶中无令牌可取时,触发限流

解决的问题:可以处理突发流量

分布式限流

分布式限流的大致思路是需要将核心计数组件放到redis中,具体的方案是使用redis中的lua脚本来实现

具体实现详见参考文档2

小结

限流只是一个保障系统的方法,在实际应用中令牌桶应当是更加常见的,但是当然也并非完美。

Java中有Guava包提供了几种限流算法的实现,同样也具有很大的参考意义。

参考文档

限流技术总结
基于redis的分布式限流方案