在Nginx中,以LIMIT开头的配置项,都是做限制功能的。这里介绍三个常用的限制模块:

1)limit_conn_zone模块:限制同一IP地址并发连接数。

2)limit_request模块:限制同一IP某段时间的访问量。

3)core模块提供的limit_rate:限制同一IP流量。

本文针对这三个模块进行配置,并验证各自的功能特点。

一、limit_conn_zone模块

通过limit_zone模块来达到限制用户连接数的目的,即限制同一用户IP地址的并发连接数。

1、配置示例

    limit_conn_zone $binary_remote_addr zone=myzone:10m;server {listen       80;server_name  localhost;location /downloads/ {limit_conn myzone 1;alias   /data/apps/;index  index.html index.htm;}}

2、指令

指令名称:limit_conn_zone(nginx1.18以后用limit_conn_zone取代了limit_conn)
语法:limit_conn_zone key zone=name:size;
默认:no
区域:http
功能:上面示例中的$binary_remote_addr是获取客户端ip地址的变量,长度为4字节,会话信息的长度为32字节。

指令名称:limit_conn
语法:limit_conn zone number;
默认:no
区域:http、server、location
功能:该指令用于为一个会话设定最大并发连接数。如果并发请求超过这个限制,那么将返回预定错误(limit_conn_status)

指令名称:limit_conn_status
语法:limit_conn_status code;
默认:limit_conn_status 503;
区域:http、server、location
功能:设置要返回的状态码以响应被拒绝的请求。

指令名称:limit_conn_log_level
语法:limit_conn_log_level info | notice | warn | error
默认值:error
区域:http、server、location
功能:该指令用于设置日志的错误级别,当达到连接限制时,将会产生错误日志。

上面配置的示例中,没有显示配置limit_conn_status 、limit_conn_log_level,如果没有配置,则启用它们的默认值。

3、测试

我这里测试下载app包,用ab命令进行模拟并发访问。

[root@localhost ~]# ab -n 10 -c 10 http://192.168.0.171/downloads/test.apk

-n:总请求数

-c:并发个数

结果:

Concurrency Level:      10
Time taken for tests:   0.005 seconds
Complete requests:      10
Failed requests:        1(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors:           0
Non-2xx responses:      9
Total transferred:      16483538 bytes

可以看到,这次测试完成了10个并发连接,其中9个返回的是非200状态码。再来看一下Nginx日志:

[root@localhost logs]# tail access.log
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:13:43:09 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"

10个并发连接,其中只有1个返回200状态码,其余9个都是503状态,这样的测试结果和设定的测试结果相符。

二、limit_request模块

使用ngx_http_limit_req_module模块可以限制某一IP在一段时间内对服务器发起请求的连接数,该模块为内置模块。

1、配置示例

    limit_req_zone $binary_remote_addr zone=zone2:10m rate=1r/s;server {listen       80;server_name  localhost;location /downloads/ {limit_req zone=zone2 burst=5 nodelay;alias   /data/apps/;index  index.html index.htm;}}

2、指令

指令名称:limit_req_zone
语法:limit_req_zone key zone=name:size rate= number r/s
默认值:no
区域:http
使用示例:limit_req_zone $binary_remote_addr zone=zone2:10m rate=1r/s
对于上面的示例:

$binary_remote_addr :表示通过remote_addr这个标识来做限制。
zone=zone2:10m:表示生成一个 10M ,名字为 zone2 的内存区域,用来存储访问的频次信息
rate=1r/s:表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,即每秒只处理一个请求,还可以有比如 30r/m , 即限制每 2秒 访问一次,即每 2秒 才处理一个请求。

指令名称:limit_req
语法:limit_req zone=name [burst=number] [nodelay | delay=number];
默认值:no
区域:http、server、location
使用示例:limit_req zone=zone2 burst=5 nodelay;

zone=zone:设置使用哪个配置名来做限制,与上面 limit_req_zone 里的 name 对应
burst=5 :这个配置的意思是设置一个大小为5的缓冲区,当有大量请求过来时,超过访问频次限制 rate=1r/s 的请求可以先放到这个缓冲区内等待,但是这个缓冲区只有5个位置,超过这个缓冲区的请求直接报503并返回。
nodelay:如果设置,会在瞬间提供处理(rate+burst)个请求的能力,请求超时(rat+burst)的时候直接返回503,永远不存在请求需要等待的情况。如果没有设置,则所有请求会依次等待排队;

指令名称:limit_req_status
语法:limit_req_status code;
默认:limit_req_status 503;
区域:http、server、location
功能:设置要返回的状态码以响应被拒绝的请求。

指令名称:limit_req_log_level
语法:limit_req_log_level info | notice | warn | error;
默认:limit_req_log_level error;
区域:http、server、location
功能:该指令用于设置日志的错误级别,当达到连接限制时,将会产生错误日志。

上面配置的示例中,没有显示配置limit_req_statuslimit_req_log_level,如果没有配置,则启用它们的默认值。

举个例子来更好的理解上面的rate=1r/sburst=5

第一秒: 来了6个请求 - 1 个处理 - 5个等待
第二秒:来了2个请求 - 1个处理 - 5个等待 - 1 个丢弃上面总共8个请求,时间2秒,2秒处理了2个请求,还剩6个,但是缓冲队列只能存放5个请求,剩下1个丢弃。或者第一秒:来了10个请求 - 1个处理 - 5个等待 - 4个丢弃

就是按照这样的方式来计算的,也就是说,上面的配置,每秒最多只能保持6个请求,但是每秒最多只能处理1个请求。

3、测试

本模块测试分为三种不同的方式进行测试验证:

1)不加burst和不加nodelay

2)加burst和不加nodelay

3)加burst和加nodelay

测试1-不加burst和不加nodelay

配置如下:

    limit_req_zone $binary_remote_addr zone=zone2:10m rate=1r/s;server {listen       80;server_name  localhost;location /downloads/ {limit_req zone=zone2;alias   /data/apps/;index  index.html index.htm;}}

通过ab命令模拟并发访问:

[root@localhost ~]# ab -n 10 -c 10 http://192.168.0.171/downloads/test.apk
...省略
Concurrency Level:      10
Time taken for tests:   0.005 seconds
Complete requests:      10
Failed requests:        1(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors:           0
Non-2xx responses:      9
Total transferred:      16483538 bytes
...省略

通过ab测试后的结果为10个并发连接,只有1个成功,剩余9个都返回非200状态码,查看Nginx日志:

[root@localhost logs]# tail access.log
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:06:56 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"

1秒钟的10次请求,只有1个返回200,剩余全是503请求被拒绝。

得出的结论是:不加burst和不加nodelay的情况下,rate=1r/s 1秒钟只能处理1个请求,剩余的所有请求都会直接返回503。

测试2-加burst和不加nodelay

配置如下:

    limit_req_zone $binary_remote_addr zone=zone2:10m rate=1r/s;server {listen       80;server_name  localhost;location /downloads/ {limit_req zone=zone2 burst=5;alias   /data/apps/;index  index.html index.htm;}}

通过ab命令模拟并发访问:通过ab命令模拟并发访问:

[root@localhost ~]# ab -n 10 -c 10 http://192.168.0.171/downloads/test.apk
...省略
Concurrency Level:      10
Time taken for tests:   5.006 seconds
Complete requests:      10
Failed requests:        6(Connect: 0, Receive: 0, Length: 6, Exceptions: 0)
Write errors:           0
Non-2xx responses:      4
Total transferred:      98882678 bytes
...省略

通过ab测试后的结果为10个并发连接,其中失败了4个,成功了6个。

在本次的测试中,使用burst=5建立以一个可以存放5个并发连接的缓冲区。

第一秒:10个连接并发请求,1个处理 5个等待,4个丢弃;
第二秒:1个处理 4 个等待;
第三秒:1个处理 3 个等待;
第四秒:1个处理 2 个等待;
第五秒:1个处理 1 个等待;
第六秒:1个处理 完毕。

通过上面的推算,一共需要 6 秒才能处理完所有的请求,查看 Nginx 日志,验证推算是不是正确:

[root@localhost logs]# tail access.log
192.168.0.171 - - [13/Mar/2020:15:19:37 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:37 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:37 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:37 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:37 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:38 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:39 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:40 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:41 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:19:42 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"

通过日志,可以看出,第一秒处理了1个请求,拒绝了4个连接,剩下的请求分别是每秒 1个连接请求的处理。

得出的结论是:加burst和不加nodelay的情况下,rate=1r/s burst=5 处理1个,缓存5个后续1秒一个的处理,其他的全部丢弃。

测试3-加burst和加nodelay

配置如下:

    limit_req_zone $binary_remote_addr zone=zone2:10m rate=1r/s;server {listen       80;server_name  localhost;location /downloads/ {limit_req zone=zone2 burst=5 nodelay;alias   /data/apps/;index  index.html index.htm;}}

通过ab命令模拟并发访问:通过ab命令模拟并发访问:

[root@localhost ~]# ab -n 10 -c 10 http://192.168.0.171/downloads/test.apk
...省略
Concurrency Level:      10
Time taken for tests:   0.022 seconds
Complete requests:      10
Failed requests:        6(Connect: 0, Receive: 0, Length: 6, Exceptions: 0)
Write errors:           0
Non-2xx responses:      4
Total transferred:      98882678 bytes
...省略

10个连接请求,很快就直接返回了,其中4个非200错误,6个成功。查看Nginx日志:

[root@localhost logs]# tail access.log
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 503 206 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"
192.168.0.171 - - [13/Mar/2020:15:28:24 +0800] "GET /downloads/test.apk HTTP/1.0" 200 16479754 "-" "ApacheBench/2.3"

这次的测试结果,同一秒钟,处理了rate+burst个请求,其他的全部返回连接请求拒绝。

4、总结

通过测试的三种情况,返回了不同的结果,因此有必要详细说明:

1)不加 burst 和 不加 nodelay 的情况:按照 rate 设定的规则,严格执行。例如:rate=1r/s ,则1秒只处理1个请求,其他的全部返回连接503。

2)加 burst 和 不加 nodelay 的情况:首先按照 rate 规则处理,并且缓存 burst 个连接,剩余的全部返回503,后续缓存的 burst 按照 rate 规则进行处理。

3)加 burst 和 nodelay 的情况:第一次处理 rate+burst 个连接请求,剩余的请求全部返回 503。

四、limit_rate_ip限制流量

对于提供下载的网站,肯定是要进行流量控制的。Nginx通过core模块的limit_rate等指令可以做到限流的目的。

1、示例

    server {listen       80;server_name  localhost;location /downloads/ {limit_rate_after 3m;limit_rate 512K;alias   /data/apps/;index  index.html index.htm;}}

2、指令

指令名称:limit_rate
语法:limit_rate speed;
默认值:no
区域:http、server、location
示例:limit_rate 512k;
功能:该指令用于指定向客户端传输数据的速度,速度的单位是每秒传输的字节数。注意:该限制只是针对一个连接的设定,也就是说,如果同时有2个连接,那么它的速度将会是该指令设置的两倍。

指令名称:limit_rate_after
语法:limit_rate_after size;
默认值:limit_rate_after 1m;
区域:http、server、location
示例:limit_rate_after 3m;
功能:以最大的速度下载 size大小后,在进行 limit_rate speed 限速,例如:limit_rate_after 3m 解释为:以最大的速度下载3m后,再进行限速。

3、测试

测试前疑问:对于这个模块是通过什么来进行限速的呢? 上面的两个模块都有声明 $binary_remote_addr 远端ip地址进行操作的,而limit_rate什么都没规定。针对这个问题,做以下测试:

配置如下:

    server {listen       80;server_name  localhost;location /downloads/ {limit_rate_after 3m;limit_rate 512K;alias   /data/apps/;index  index.html index.htm;}}

表示:正常速度下载 3m数据后,限速 512K 的速度下载。

这次通过curl来下载文件。

如果同时开启多个终端下载呢?

连接-1

连接-2

因为 limit_rate 并没有声明以什么条件作为限制,所以同一个ip无论发起多少个请求,每个请求都会是 512k 下载。在迅雷等多种下载软件中,使用多线程的方式下载同一个文件,这个速度就翻倍了。 那这个限速就形同虚设。

因此,如果要进行限速,可以和 limit_conn_zone 模块配合进行使用。配置如下:

    limit_conn_zone $binary_remote_addr zone=myzone:10m;server  {listen       80;server_name  localhost;location /downloads/ {limit_conn myzone 1;limit_rate_after 3m;limit_rate 512K;alias   /data/apps/;index  index.html index.htm;}}

再进行通主机多线程下载:

连接-1

连接-2

当第一个连接在下载的时候发起第二个连接,服务器会直接返回连接拒绝503,这样就达到了限速的目的。

4、总结

当需要进行限速操作时,需要limit_ratelimit_conn模块联合起来使用才能达到限速的效果。

参考文章:
https://www.cnblogs.com/hukey/p/10498544.html

Nginx-限制并发、访问速率、流量相关推荐

  1. php-cgi和php-fpm,Windows环境下解决Nginx+php并发访问阻塞问题。

    php-cgi 是运行php, php-fpm是守护php-cgi进程 nginx配置目录运行php         location  ~ \.php$         {              ...

  2. nginx实现并发连接与IP流量限速功能

    目录 参考 前言 limit_conn_zone 模块 配置 测试 测试小文件 测试大文件 总结 limit_request 模块 配置 测试 测试1 - 不加 burst 和 不加 nodelay ...

  3. Nginx限制对代理HTTP资源的访问速率

    Nginx限制对代理HTTP资源的访问速率 本文介绍了如何设置连接请求的最大数量,或从服务器下载内容的最大速率. 介绍 限制连接数 限制请求率 测试请求速率限制 处理过多的请求 延迟过多的请求 同步许 ...

  4. nginx代理后,获取真实IP,做并发访问限制的方法(限流)

    站点在运行时,为了防止DDoS 攻击.或内部接口调用造成的数据迸发,nginx提供了limit限流模块: HttpLimitZoneModule 限制同时并发访问的数量HttpLimitReqModu ...

  5. 网站大流量高并发访问的处理解决办法

    --------目录--------- 1.硬件升级 2.服务器集群.负载均衡.分布式 3.CDN 4.页面静态化 5.缓存技术(Memcache.Redis) 以上为架构层面 以下为网站本地项目层面 ...

  6. PHP-高并发和大流量的解决方案

    一  高并发的概念 在互联网时代,并发,高并发通常是指并发访问.也就是在某个时间点,有多少个访问同时到来. 二  高并发架构相关概念 1.QPS (每秒查询率) : 每秒钟请求或者查询的数量,在互联网 ...

  7. 实现网站的高并发访问

      高并发访问的核心原则其实就一句话"把所有的用户访问请求都尽量往前推". 如果把来访用户比作来犯的"敌人",我们一定要把他们挡在800里地以外,即不能让他们的 ...

  8. mysql高并发和大流量_高并发-高并发和大流量解决方案

    高并发架构相关概念 并发 并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,并且这几个程序都是在同一个处理机上运行,担任一个时刻点上只有一个程序在处理机上运行. 我们所说的 ...

  9. 高并发和大流量解决方案

    #高并发架构相关概念# 并发: 在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任意一个时刻上只有一个程序在处理机上运行. 我们说的高并 ...

最新文章

  1. Android输入输出机制之来龙去脉之前生后世
  2. 面试题之第一部分(Python基础篇) 80题
  3. pycharm 运行celery_Celery全面学习笔记
  4. codeforces#320(div2) D Or Game 贪心
  5. php源码编译常见错误解决方案
  6. 2017年经历的那些灵异事件
  7. 支付宝批量转账接口使用全过程 一一介绍
  8. 操作系统实验报告清华大学LAB1
  9. vue-cli搭建项目引入jquery和jquery-weui步骤详解
  10. 计算机编程常用术语英文词汇
  11. Hprose轻松实现远程过程调用(RPC)
  12. 8081端口导致React Native启动失败
  13. 2020最新抖音上热门技巧你知道了几个?
  14. java让星星闪烁,js实现星星闪特效
  15. 计算机科学专业博士,美国留学:布兰迪斯大学计算机科学博士专业简介
  16. 安装autoconf
  17. 浙大PTA数据结构与算法题目集(中文)题解集复习用
  18. 一个海底隧道中只有一个车道,规定同一个方向的可以连续过隧道。某方向有列车过隧道时,另一个方向的列车就要等待, 现在东岸和西岸都有列车要过隧道,如果把每个过隧道的列车看作一个进程,使用P、V操作
  19. H.264_AVC视频编码技术学习
  20. 地震波ifft matlab,地震波观测系统的MATLAB仿真报告.doc

热门文章

  1. ELKF搭建详细步骤(Elasticsearch+logstash+kibana+filebeat)
  2. 胃口不好吃什么食物好 这几样开胃消食
  3. 哈工大2012年接收外校推荐免试硕士研究生工作办法
  4. R语言基础——日期数据
  5. 银行核心项目之测试阶段
  6. 小型点阵屏后台监控系统研发
  7. Excel:如何将vlookup 中#N/A全部替换为0。
  8. 无眠的滴滴,不再高傲
  9. 【原创】新韭菜日记35--20190313 第一次没满仓,试试定力,另外第一次开始技术分析选股和买卖
  10. 霍尔电流传感器在光伏汇流箱的应用