关注「Java视界」公众号,获取更多技术干货

分布式限流方案

一、限流算法

主要的限流算法包含:漏桶算法令牌桶算法计数器

每种限流算法详细可以参考这里

二、分布式限流方案

一般也就分为三种:Gateway限流redis+lua实现限流nginx限流

2.1 Gateway限流

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的状态码。
在这里插入图片描述

2.2 redis+lua

1.在服务中引入lua脚本
在这里插入图片描述
2.读取lua
在这里插入图片描述
3.判断是否需要限流的代码
在这里插入图片描述
在这里插入图片描述
4. 上面我们可以看到正常情况下10s内只产生3个令牌,我们来看下效果
在这里插入图片描述
可以看到10秒内只有前三个请求通过,其他的都是被拒绝的,过了10s后又会有三个请求可以通过,这完全符合我们预期的效果。

2.3 Nginx限流

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

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

具体配置:

限制访问速率

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server { 
    location / { 
        limit_req zone=mylimit;
    }
}

上述规则限制了每个IP访问的速度为2r/s,并将该规则作用于根目录。如果单个IP在非常短的时间内并发发送多个请求,结果会怎样呢?
在这里插入图片描述
使用单个IP在10ms内发并发送了6个请求,只有1个成功,剩下的5个都被拒绝。我们设置的速度是2r/s,为什么只有1个成功呢,是不是Nginx限制错了?当然不是,是因为Nginx的限流统计是基于毫秒的,我们设置的速度是2r/s,转换一下就是500ms内单个IP只允许通过1个请求,从501ms开始才允许通过第二个请求。

补充一、怎么让系统承受更大的访问量?

一方面是从请求上来说,将多个请求合并成一个请求发送,减少请求次数。
另一方面是把请求都改成异步的,让请求过来之后就直接返回成功,后面后台继续处理剩下的逻辑。

posted @ 2022-06-25 14:01  沙滩de流沙  阅读(254)  评论(0编辑  收藏  举报

关注「Java视界」公众号,获取更多技术干货