nginx也能做限流?怎么做的

·  阅读 190

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

写在前面

Nginx不仅可以做Web服务器、做反向代理、负载均衡,还可以做限流系统。此处我们就Nginx为例,介绍一下如何配置一个限流系统。

以前也写过关于nginx的文章:

nginx知多少(值得一看)

先简单聊下漏桶算法

Nginx使用的限流算法是漏桶算法。,所以我们先简单了解下漏桶算法再进行下面的学习。

漏桶算法,又称leaky bucket。为了理解漏桶算法,我们看一下对于该算法的示意图:

image.png

从图中我们可以看到,整个算法其实十分简单。首先,我们有一个固定容量的桶,有水流进来,也有水流出去。对于流进来的水来说,我们无法预计一共有多少水会流进来,也无法预计水流的速度。但是对于流出去的水来说,这个桶可以固定水流出的速率。而且,当桶满了之后,多余的水将会溢出。

我们将算法中的水换成实际应用中的请求,我们可以看到漏桶算法天生就限制了请求的速度。当使用了漏桶算法,我们可以保证接口会以一个常速速率来处理请求。所以漏桶算法天生不会出现临界问题。

漏桶算法可以粗略的认为就是注水漏水过程,往桶中以一定速率流出水,以任意速率流入水,当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。

好 了解完该算法。我们进入正题 怎么配置让nginx也能做到限流

配置模块

在http块中,配置基础的限流配置:

01 http {
02     limit_req_zone$binary_remote_addr zone=mylimit:10m rate=10r/s;
03   
04     server {
05         location /test/ {
06             limit_reqzone=mylimit;
07    
08             proxy_pass http://api;
09         }
10     }
11 }
复制代码

上面代码很熟悉吧,其中Server定义的是一个服务器接口。而第2行和第6行配合完成了一个限流设置,下面解释一下这两行做的事情:

limit_req_zone命令在Nginx的配置文件中专门用于定义限流,它必须被放在http块中,否则无法生效,因为该命令只在http中被定义。

该字段包括三个参数。我们一起看下

  • 第一个参数,就是键(key),即值$binary_remote_addr所在的位置,它代表的是我们的限流系统限制请求所用的键。

此处,我们使用了$binary_remote_addr,它是Nginx内置的一个值,代表的是客户端的IP地址的二进制表示。因此换言之,我们的示例配置,是希望限流系统以客户端的IP地址为键进行限流。

  • 第二个参数是限流配置的共享内存占用(zone)。为了性能优势,Nginx将限流配置放在共享内存中,供所有Nginx的进程使用,因为它占用的是内存,所以我们希望开发者能够指定一个合理的、既不浪费又能存储足够信息的空间大小。根据实践经验,1MB的空间可以储存16000个IP地址。

在该声明中,我们声明了一个名叫mylimit(我的限制)的内存空间,然后它的大小是10M,即可以存储160000个IP地址

  • 第三个配置就是访问速率(rate)了,格式是用左斜杠隔开的请求数和时间单位。这里的访问速率就是最大速率,因此10r/s就是每秒10个请求。通过这台Nginx服务器访问后端服务器的请求速率无法超过每秒10个请求。

第6行中,我们使用limit_req命令,声明该API需要一个限流配置,而该限流配置所在位置(zone)就是mylimit。这样一来,所有发往该API的请求会先读到第6行的限流配置,然后根据该限流配置mylimit的名称找到声明在第2行的参数,然后决定该请求是否应该被拒绝。

注意,这样也许还不够。不要忘了,Nginx使用的漏桶算法,不是时间窗口算法,我们前文介绍中说过,漏桶算法是有两个参数可以配置的!

配置峰值。Nginx漏桶算法的峰值属性在API中设置。参数名为burst。如下:

01 http {
02     limit_req_zone$binary_remote_addr zone=mylimit:10m rate=10r/s;
03
04     server {
05         location /test/ {
06             limit_reqzone=mylimit burst=20;
07
08             proxy_pass http://api;
09         }
10     }
11 }
复制代码

在第6行中,我们只需要在声明limit_req的同时,指定burst就可以了,此处我们指定burst为20,即漏桶算法中我们的“桶”最多可以接受20个请求。

这样一个Nginx的限流系统就配置完毕了,是不是贼简单 哈哈 ,你们也可以试下。今天我们就学到这里,下期再见,下期会进入队列专题,欢迎大家点击头像关注专栏。我们一起学习,加油 !!!

弦外之音

感谢你的阅读,如果你感觉学到了东西,您可以点赞,关注。也欢迎有问题我们下面评论交流

加油! 我们下期再见!

给大家分享几个我前面写的几篇骚操作

copy对象,这个操作有点骚!

干货!SpringBoot利用监听事件,实现异步操作

分类:
后端
标签:
分类:
后端
标签: