高可用实践之服务限流(一)

本文介绍了服务限流的目的和几种常用的限流算法,包括固定窗口、滑动窗口、令牌桶和漏桶算法。讨论了它们的优缺点,并详细解释了如何在分布式环境下实现限流,提供了基于Redis的分布式限流解决方案,适用于不同场景的服务保护。
摘要由CSDN通过智能技术生成

目的

在流量高峰期或因为活动、热点事件、恶意攻击等原因导致流量突增时,通过对请求流量速率进行限制,保证请求流量在合理范围内,避免因为超出预期的大流量导致服务整体性能下降、响应缓慢或不可用。在触发限流后,可以通过拒绝部分服务、等待、排队、降级等策略保护业务系统。

常用限流算法

固定窗口算法

  1. 定义:限制固定时间段内,特定api的最大请求量,如限制每秒最多请求100次,超出100次触发限流策略。
  2. 优点:实现简单直观
  3. 缺点:
    1. 请求分布不均,不能平滑流量,容易出现部分时刻“服务不可用”的表现。如1秒内,前10ms请求100次,导致后990ms全部请求被拒绝。即请求分布不均,部分请求在某个时刻聚集,导致这个时刻所属的时间窗口内的其他时刻被拒绝。
    2. 出现流量尖峰,容易导致单位时间超出服务器预期负载,如预期单位时间1s内请求100次,上一秒的最后10ms请求100次,下一秒的最早10ms请求100次,则在单位时间1秒内,出现200次请求,超出服务承载预期。

滑动窗口算法

定义

将一个时间区间划分为N个长度固定的小时间窗口,每一次请求考察当前时间往前N个连续时间窗口的请求量总和,如果超过阈值则触发限流策略。如配置请求阈值100,将1s时间划分为5个连续的时间窗口,每个窗口长度250ms,则意味这上一秒当前250ms加上一秒的最后750ms请求量不会100个请求。

优点

解决了固定窗口流量尖峰的问题,确保在任意时刻,过去窗口时间内的请求不会超出阈值。

缺点

  1. 不能解决请求分布不均的问题,即无法平滑流量
  2. 实现更复杂,需要维护时间窗口,占用内存更多,计算时间复杂度也相应变大。

令牌桶算法

定义

存在一个令牌桶计数器,每隔一定时间放入一块令牌,每次请求取出一块令牌。,令牌桶有最大容量限制,当计数器令牌数达到最大值,则不再放入,如果计数器令牌数为0,请求则触发限流策略。如每隔10ms放入一块令牌,最大令牌数为100,假设某个时刻令牌桶放满令牌,则这个时刻的前10ms能请求100次,清20ms能请求101次。

优点

  1. 解决了固定窗口流量尖峰的问题,确保在任意时刻,过去窗口时间内的请求不会超出阈值。
  2. 可以有效平滑流量,因为令牌桶的令牌是匀速放入的
  3. 相对滑动窗口更节省内存

缺点

实现复杂,时间复杂度高

注意事项

  1. 令牌桶预热

漏桶算法

定义

相对于令牌桶是固定速率放入令牌,在没有令牌的时候拒绝请求,漏桶则是固定数据漏出请求,当请求量过大,流入请求超过桶容量,则触发限流策略。具体实现时,可以将漏桶想象成一个有流量限制的先进先出的队列,在队列不为空情况下,每隔一定时间取出一个队列请求进行处理相应,如果队列已经满了,再来请求则触发限流相关策略。如限制每10ms漏出一个请求,桶容量为100个请求,则每10ms最多能处理一个请求。

优点

实现相对简单,可以限制服务请求速率,并且稳定在一个常速。

缺点

对于特发流量处理效率过低,在没有到达服务器负载阈值,也只能串行处理请求。

分布式限流

可以基于Redis实现分布式限流。

基于固定窗口的分布式限流实现

我们可以基于Redis来实现固定窗口的分布式限流算法:

可以为每个请求路径配置一个有超时时间的计数器,每次请求给计数器加一,如果超过限制阈值,则返回限流标识,具体实现如下:

// 限流桶
private static final String BUCKET = "BUCKET";

/**
 * 基于redis的固定窗口分布式限流
 * @param point 限流方法标识
 * @param limit 限流阈值
 * @param timeout 固定时间窗口大小
 * @return 如果触发限流,返回-1,否则返回当前请求在固定窗口里的请求计数
 */
public long acquireTokenFromBucket(String point, int limit, int timeout) {
   
    Jedis jedis = jedisPool.getResource();
    try {
   
        // 标识当前请求
        Long counter = jedis.incr(BUCKET + point
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值