分布式限流方案(gateway限流,redis+lua实现限流,nginx限流)

分布式限流方案(gateway限流,redis+lua实现限流,nginx限流)

限流算法

计数器

计数器比较简单粗暴,比如我们限制的是1s能够通过的请求数,实现的思路就是从第一个请求进来开始计时,在接下来的1s内,每个请求进来请求数就+1,超过最大请求数的请求会被拒绝,等到1s结束后计数清零,重新开始计数。
这种方式有个很大的弊端:比如前10ms已经通过了最大的请求数,那么后面的990ms的请求只能拒绝,这种现象叫做“突刺现象”。

漏桶算法

就是桶底出水的速度恒定,进水的速度可能快慢不一,但是当进水量大于出水量的时候,水会被装在桶里,不会直接被丢弃;但是桶也是有容量限制的,当桶装满水后溢出的部分还是会被丢弃的。
在这里插入图片描述

算法实现:可以准备一个队列来保存暂时处理不了的请求,然后通过一个线程池定期从队列中获取请求来执行。

令牌桶算法

令牌桶就是生产访问凭证的一个地方,生产的速度恒定,用户访问的时候当桶中有凭证时就可以获取到凭证
在这里插入图片描述

实现方案:
Guava RateLimiter限流:
Guava RateLimiter是一个谷歌提供的限流,其基于令牌桶算法,比较适用于单实例的系统。

限流方案具体实现

网关限流

Spring Cloud Gateway中提供了RequestRateLimiterGatewayFilterFactory类,这个是基于令牌桶实现的。它内置RedisReteLimiter,依赖于Redis存储限流配置和统计数据,我们也可以通过继承
org.springframework.cloud.gateway.filter.ratelimit.AbstractRateLimiter 或者是实现
org.springframework.cloud.gateway.filter.ratelimit.RateLimiter 接口来实现自己的RateLimiter。
具体实现如下:

  1. 首先在网关服务引入依赖
    在这里插入图片描述

  2. 引入的配置如下
    在这里插入图片描述

  3. 可以实现基于三个维度的限流:
    在这里插入图片描述

上面所示的配置是每秒产生的令牌数量是1,当我们的请求速度大于这个数值时,就会返回429的状态码
在这里插入图片描述

到这里我们在gateway层面的限流就实现了。

redis+lua

  1. 在服务中引入lua脚本
    在这里插入图片描述

  2. 引用lua
    在这里插入图片描述

  3. 判断是否需要限流相关代码
    在这里插入图片描述
    在这里插入图片描述

  4. 上面我们可以看到正常情况下10s内只产生3个令牌,我们来看下效果
    在这里插入图片描述

可以看到10秒内只有前三个请求通过,其他的都是被拒绝的,过了10s后又会有三个请求可以通过,这完全符合我们预期的效果。

Nginx限流

限制访问频率:
Nginx可以通过参数ngx_http_limit_req_module模块来限制访问频率,使用的漏桶算法实现的;可以通过limit_req_zone命令以及limit_req命令限制单个ip的请求处理频率。

限制连接数:
ngx_http_limit_conn_module模块提供了并发连接数的功能,可以使用limit_conn_zone命令和limit_conn进行配置,也是基于漏桶算法实现的。

作者后面技术除了写文章外再维护一个开源的项目,所以有源码需求的同学可以关注下木木,预计今年过年期间可以开始开放。

猜你喜欢

转载自blog.csdn.net/qq_41979344/article/details/113105303