常见的限流算法有哪些

限流是保护系统稳定性的重要手段,防止系统因突发流量过载而崩溃。常见的限流算法主要包括以下几种,每种算法都有其适用场景和实现方式。

  1. 计数器算法(Fixed Window Counter)
    原理:
    ● 使用一个固定窗口(时间段)内的计数器,记录请求的数量。
    ● 若计数器超过设定的阈值,则拒绝后续请求。
    实现:
  2. 定义一个时间窗口(如1秒)。
  3. 在窗口内维护一个计数器,接收到请求时计数器+1。
  4. 若计数器超过阈值,则限流;否则允许。
    优点:
    ● 简单易实现,适用于低精度的限流需求。
    缺点:
    ● 边界问题:窗口边界处可能产生突发流量。例如,当前窗口接近阈值,新窗口开始时流量激增。
  5. 滑动窗口计数器(Sliding Window Counter)
    原理:
    ● 将固定窗口进一步细分为更小的时间片段。
    ● 根据当前时间的滑动,将多个时间片段内的请求数量进行累加。
    实现:
  6. 将1秒分为多个时间片段(如100毫秒)。
  7. 使用一个队列存储各时间片段的计数。
  8. 请求时移除过期的时间片段,并累计最新的请求数。
    优点:
    ● 缓解固定窗口算法的边界问题。
    ● 流量控制更加平滑。
    缺点:
    ● 实现较为复杂,存储和计算开销增加。
  9. 漏桶算法(Leaky Bucket)
    原理:
    ● 将请求存入一个“桶”中,以恒定速率从桶中取出处理。
    ● 若请求到达速度超过出水速度,则多余的请求被丢弃或排队。
    实现:
  10. 维护一个队列表示漏桶。
  11. 按固定速率处理请求。
  12. 若队列满,则丢弃新请求。
    优点:
    ● 能平滑突发流量,将其转化为稳定输出。
    ● 控制请求处理速率。
    缺点:
    ● 丢弃超量请求可能导致用户体验下降。
  13. 令牌桶算法(Token Bucket)
    原理:
    ● 系统按固定速率向桶中加入“令牌”。
    ● 每次请求需要消耗一个令牌,若令牌不足,则拒绝请求。
    实现:
  14. 维护一个桶存储令牌,设定令牌生成速率和桶容量。
  15. 请求时,检查桶内是否有足够令牌:
    ● 有:扣除相应令牌,允许请求。
    ● 无:拒绝请求。
    优点:
    ● 支持突发流量处理(通过允许提前消费桶中积累的令牌)。
    ● 限流效果较平滑。
    缺点:
    ● 相比漏桶算法实现稍复杂。
  16. Sliding Log(滑动日志算法)
    原理:
    ● 记录每个请求的时间戳。
    ● 根据当前时间窗口计算历史请求数量,决定是否限流。
    实现:
  17. 使用一个有序集合(如Redis的zset)存储时间戳。
  18. 请求时清理超出时间窗口的过期时间戳,并统计剩余时间戳数量。
  19. 若数量未超限,则允许请求;否则限流。
    优点:
    ● 精度高,适合精细化限流。
    缺点:
    ● 存储开销大,尤其在高并发下可能性能较低。
  20. 分布式限流方案
    在分布式系统中,单节点限流可能失效,需考虑全局限流。
    常用方案:
  21. 基于Redis:
    ● 利用Redis的单线程特性实现原子操作。
    ● 如使用INCR、EXPIRE实现计数器,或zset实现滑动日志。
  22. 基于一致性哈希:
    ● 将限流逻辑分布到不同节点,按哈希分配请求。
  23. 基于分布式锁:
    ● 通过分布式锁协调各节点的限流操作。
    优点:
    ● 支持跨节点的流量管理。
    缺点:
    ● 需要额外的分布式协调开销。
  24. 基于队列的限流
    通过消息队列(如RabbitMQ、Kafka)对流量进行控制:
  25. 请求先进入消息队列。
  26. 消费者以固定速率处理队列中的请求。
    优点:
    ● 适合异步处理场景,天然支持流量削峰。
    缺点:
    ● 实时性较差。
  27. 综合限流架构
    在实际应用中,常根据业务需求结合多种限流算法。例如:
  28. 漏桶算法控制请求速率。
  29. 令牌桶算法允许短时间内的突发流量。
  30. Redis滑动日志实现分布式限流。
    选择限流算法的依据
    ● 流量特性: 是否存在突发流量。
    ● 性能要求: 计算复杂度、存储开销。
    ● 系统架构: 单节点或分布式场景。
    ● 业务需求: 允许延迟处理还是即时拒绝。
    对比总结:
    算法 是否支持突发流量 实现难度 并发性能 适用场景
    计数器 否 简单 较高 简单限流场景
    滑动窗口计数器 部分支持 较复杂 较高 边界平滑的限流
    漏桶 否 中等 高 平滑流量,限速处理
    令牌桶 是 中等 高 支持突发流量的限速
    滑动日志 是 较复杂 较低 精细化限流,高精度控制
    分布式限流 取决于算法 复杂 高 分布式系统中的限流
    消息队列 是 较简单 较高 削峰填谷,异步处理流量
    根据业务需求选择合适的算法,可以在保护系统的同时,尽可能提高流量的利用率和用户体验。
posted @ 2024-12-12 14:26  summer学Java  阅读(52)  评论(0)    收藏  举报