常见分布式限流方案

常见分布式限流方案

限流分类

合法性验证限流

比如验证码、IP 黑名单等,这些手段可以有效的防止恶意攻击和爬虫采集;

容器限流

比如 Tomcat、Nginx 等限流手段,其中 Tomcat 可以设置最大线程数(maxThreads),当并发超过最大线程数会排队等待执行;而 Nginx 提供了两种限流手段:一是控制速率,二是控制并发连接数;

服务端限流

比如我们在服务器端通过限流算法实现限流,此项也是我们本文介绍的重点。

常见的6种限流方案

1.Tomcat 使用 maxThreads 设置请求线程数来实现限流

实现方案:
进入tomcat的conf/server.xml文件配置中,然后找到如下代码:

<Connector port="8080" protocol="HTTP/1.1"
          connectionTimeout="20000"
          maxThreads="150"
          redirectPort="8443" />

maxThreads就是tomcat的最大线程数,当请求的并发大于此值,请求就会排队执行。
此值默认为 150(Tomcat 版本 8.5.42),每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用,Windows 每个进程中的线程数不允许超过 2000,Linux 每个进程中的线程数不允许超过 1000。

2.nginx通过 limit_req_zone 和 burst 来实现速率限流

实现方案:在nginx主文件配置中写入如下代码:

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

以上代码的意思是限制每个ip访问的速度为每秒2次请求,但是nginx对时间是更加严格的,细分到500ms为单位划分,其真实情况是1r/500ms。

上面的请求限制太过于苛刻,对于单位时间内无法执行的请求直接拒绝。真实情况应该用ip继续细分而不是只统计单位时间内请求次数。我们可以使用burst配置,代码如下:

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

burst=4 表示每个 IP 最多允许4个突发请求.这意味着500ms内一个ip发起6次请求,第一个请求立即执行,接下来4个请求进入队列等待执行,最后一个请求直接拒绝。

3.nginx通过 limit_conn_zone 和 limit_conn 两个指令控制并发连接的总数

实现方案:
在nginx主配置文件中写入如下代码:

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}

上面的10M是指允许使用10MB内存保存变量值

$binary_remote_addr和$server_name。
其中 limit_conn perip 10 表示限制单个 IP 同时最多能持有 10 个连接;limit_conn perserver 100 表示 server 同时能处理并发连接的总数为 100 个。

只有当 request header 被后端处理后,这个连接才进行计数。

4.服务端使用时间窗口算法借助 Redis 的zset实现限流

实现方案:
所谓的滑动时间算法指的是以当前时间为截止时间,往前取一定的时间,比如往前取 60s 的时间,在这 60s 之内运行最大的访问数为 100,此时算法的执行逻辑为,先清除 60s 之前的所有请求记录,再计算当前集合内请求数量是否大于设定的最大请求数 100,如果大于则执行限流拒绝策略,否则插入本次请求记录并返回可以正常执行的标识给客户端。
滑动时间窗口如下图所示:

其中每一小个表示 10s,被红色虚线包围的时间段则为需要判断的时间间隔,比如 60s 秒允许 100 次请求,那么红色虚线部分则为 60s。
下面是算法实现,每3秒最多请求10次,代码如下:
借助 Jedis 包来操作 Redis,实现在 pom.xml 添加 Jedis 框架的引用,配置如下:

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值