可以通过ngx_http_limit_conn_module和ngx_http_limit_req_module模块来实现限速的功能。
该模块主要限制下载速度。
并发限制 配置示例 http { ... limit_conn_zone $binary_remote_addr zone=test:10m; ... server { ... limit_conn test10; ... } } 说明:首先用limit_conn_zone定义了一个内存区块索引test,大小为10m,它以$binary_remote_addr作为key。 该配置只能在http里面配置,不支持在server里配置。 limit_conn 定义针对test这个zone,并发连接为10个。在这需要注意一下,这个10指的是单个IP的并发最多为10个。 速度限制 location ~ /download/ { ... limit_rate_after 512k; limit_rate 150k; ... } 说明:limit_rate_after定义当一个文件下载到指定大小(本例中为512k)之后开始限速; limit_rate 定义下载速度为150k/s。 注意:这两个参数针对每个请求限速。该模块主要用来限制请求数。
limit_req_zone 语法: limit_req_zone $variable zone=name:size rate=rate; 默认值: none 配置段: http 设置一块共享内存限制域用来保存键值的状态参数。 特别是保存了当前超出请求的数量。 键的值就是指定的变量(空值不会被计算)。 如limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 说明:区域名称为one,大小为10m,平均处理的请求频率不能超过每秒一次,键值是客户端IP。 使用$binary_remote_addr变量, 可以将每条状态记录的大小减少到64个字节,这样1M的内存可以保存大约1万6千个64字节的记录。 如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回 503 (Service Temporarily Unavailable)错误。 速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数, 所以如果你需要指定每秒处理少于1个的请求,2秒处理一个请求,可以使用 “30r/m”。 limit_req 语法: limit_req zone=name [burst=number] [nodelay]; 默认值: — 配置段: http, server, location 设置对应的共享内存限制域和允许被处理的最大请求数阈值。 如果请求的频率超过了限制域配置的值,请求处理会被延迟,所以所有的请求都是以定义的频率被处理的。 超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值, 这时,这个请求会被终止,并返回503 (Service Temporarily Unavailable) 错误。 这个阈值的默认值为0。如: limit_req_zone $binary_remote_addr zone=test:10m rate=1r/s; server { location /upload/ { limit_req zone=testburst=5; } } 限制平均每秒不超过一个请求,同时允许超过频率限制的请求数不多于5个。 如果不希望超过的请求被延迟,可以用nodelay参数,如: limit_req zone=testburst=5 nodelay;示例
http { limit_req_zone $binary_remote_addr zone=test:10m rate=1r/s; server { location ^~ /download/ { limit_req zone=testburst=5; } } }设定白名单IP
如果是针对公司内部IP或者lo(127.0.0.1)不进行限速,如何做呢?这就要用到geo模块了。 假如,预把127.0.0.1和192.168.100.0/24网段设置为白名单,需要这样做。 在http { }里面增加: geo $limited { default 1; 127.0.0.1/32 0; 192.168.100.0/24 0; } map $limited $limit { 1 $binary_remote_addr; 0 ""; } 原来的 “limit_req_zone $binary_remote_addr ” 改为“limit_req_zone $limit”完整示例:
http { geo $limited { default 1; 127.0.0.1/32 0; 192.168.100.0/24 0; } map $limited $limit { 1 $binary_remote_addr; 0 ""; } limit_req_zone $limit zone=test:10m rate=1r/s; server { location ^~ /download/ { limit_req zone=testburst=5; } } }压测
[root@centos-03 vhost]# ab -n 5 -c 5 http://www.1.com/ This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.1.com (be patient).....done Server Software: nginx/1.14.0 Server Hostname: www.1.com Server Port: 80 Document Path: / Document Length: 10 bytes Concurrency Level: 5 Time taken for tests: 0.002 seconds Complete requests: 5 Failed requests: 0 Write errors: 0 Total transferred: 1200 bytes HTML transferred: 50 bytes Requests per second: 2403.85 [#/sec] (mean) Time per request: 2.080 [ms] (mean) Time per request: 0.416 [ms] (mean, across all concurrent requests) Transfer rate: 563.40 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 0 Processing: 1 1 0.1 1 1 Waiting: 1 1 0.0 1 1 Total: 1 1 0.1 1 1 Percentage of the requests served within a certain time (ms) 50% 1 66% 1 75% 1 80% 1 90% 1 95% 1 98% 1 99% 1 100% 1 (longest request)[root@centos-03 vhost]#
[root@centos-03 vhost]# cat /tmp/1.log (效果不明显文件太小了无压力) 127.0.0.1 - - [28/Jul/2018:07:20:24 +0800] "GET / HTTP/1.0" 200 10 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:20:24 +0800] "GET / HTTP/1.0" 200 10 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:20:24 +0800] "GET / HTTP/1.0" 200 10 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:20:24 +0800] "GET / HTTP/1.0" 200 10 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:20:24 +0800] "GET / HTTP/1.0" 200 10 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:52:39 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 503 213 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:52:39 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 503 213 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:52:39 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:07:52:39 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3"1.限制速度添加配置选项
[root@centos-03 vhost]# vim 1.conf ^C [root@centos-03 vhost]# cat 1.conf server { listen 80; server_name www.1.com; index index.html; root /data/wwwroot/www.1.com; access_log /tmp/1.log; location / { #limit_conn aming 2; limit_rate 10k; } } [root@centos-03 vhost]# [root@centos-03 vhost]# /usr/local/nginx/sbin/nginx -s reload [root@centos-03 vhost]# 2.浏览器测试下载速度,在本地添加host配置 3.下载速度变成每秒10k左右 4.改为限制为1000试试 access_log /tmp/1.log; location / { #limit_conn aming 2; limit_rate 1000k; } [root@centos-03 vhost]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@centos-03 vhost]# /usr/local/nginx/sbin/nginx -s reload [root@centos-03 vhost]# nginx访问控制-限速3 1.添加配置文件 [root@centos-03 vhost]# vim ../nginx.conf http { include mime.types; default_type application/octet-stream; limit_conn_zone $binary_remote_addr zone=aming:10m; limit_conn_status 503; limit_conn_log_level error; limit_req_zone $binary_remote_addr zone=aming1:10m rate=2r/s; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" $host $server_port'; 2.配置虚拟主机配置文件 [root@centos-03 vhost]# vim 1.conf server { listen 80; server_name www.1.com; index index.html; root /data/wwwroot/www.1.com; access_log /tmp/1.log; #location / #{ #limit_conn aming 2; #limit_rate 1000k; #} limit_req zone=aming1 burst=5; } 3.ab请求测试 [root@centos-03 vhost]# /usr/local/nginx/sbin/nginx -s reload [root@centos-03 vhost]# ab -n 10 -c 10 http://www.1.com/filebeat-6.3.1-x86_64.rpm This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.1.com (be patient).....done Server Software: nginx/1.14.0 Server Hostname: www.1.com Server Port: 80 Document Path: /filebeat-6.3.1-x86_64.rpm Document Length: 213 bytes Concurrency Level: 10 Time taken for tests: 2.509 seconds Complete requests: 10 Failed requests: 6 (Connect: 0, Receive: 0, Length: 6, Exceptions: 0) Write errors: 0 Non-2xx responses: 4 Total transferred: 76799974 bytes HTML transferred: 76797678 bytes Requests per second: 3.98 [#/sec] (mean) Time per request: 2509.443 [ms] (mean) Time per request: 250.944 [ms] (mean, across all concurrent requests) Transfer rate: 29887.10 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 0 Processing: 2 756 952.9 507 2508 Waiting: 1 752 950.0 501 2502 Total: 2 756 952.9 507 2508 Percentage of the requests served within a certain time (ms) 50% 507 66% 1008 75% 1508 80% 2012 90% 2508 95% 2508 98% 2508 99% 2508 100% 2508 (longest request) [root@centos-03 vhost]# 4.查看日志 [root@centos-03 vhost]# tail -n 10 /tmp/1.log 127.0.0.1 - - [28/Jul/2018:08:28:20 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 503 213 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:20 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 503 213 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:20 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 503 213 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:20 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 503 213 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:20 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:20 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:21 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:21 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:22 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" 127.0.0.1 - - [28/Jul/2018:08:28:22 +0800] "GET /filebeat-6.3.1-x86_64.rpm HTTP/1.0" 200 12799471 "-" "ApacheBench/2.3" [root@centos-03 vhost]# 5.添加nodelay(这样限速就不受影响了) [root@centos-03 vhost]# vim 1.conf server { listen 80; server_name www.1.com; index index.html; root /data/wwwroot/www.1.com; access_log /tmp/1.log; #location / #{ #limit_conn aming 2; #limit_rate 1000k; #} limit_req zone=aming1 burst=5 nodelay; } 6.ab测试瞬间完成(生产环境中不建议加nodelay) [root@centos-03 vhost]# !ab ab -n 10 -c 10 http://www.1.com/filebeat-6.3.1-x86_64.rpm This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.1.com (be patient).....done Server Software: nginx/1.14.0 Server Hostname: www.1.com Server Port: 80 Document Path: /filebeat-6.3.1-x86_64.rpm Document Length: 213 bytes Concurrency Level: 10 Time taken for tests: 0.021 seconds Complete requests: 10 Failed requests: 6 (Connect: 0, Receive: 0, Length: 6, Exceptions: 0) Write errors: 0 Non-2xx responses: 4 Total transferred: 76799974 bytes HTML transferred: 76797678 bytes Requests per second: 469.04 [#/sec] (mean) Time per request: 21.320 [ms] (mean) Time per request: 2.132 [ms] (mean, across all concurrent requests) Transfer rate: 3517822.45 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 0 Processing: 4 14 7.9 20 20 Waiting: 1 4 1.2 4 4 Total: 5 14 7.9 20 20 Percentage of the requests served within a certain time (ms) 50% 20 66% 20 75% 20 80% 20 90% 20 95% 20 98% 20 99% 20 100% 20 (longest request)