先贴一下官方wiki介绍:
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
ngx_http_limit_conn_module 主要限制并发数
ngx_http_limit_req_module 主要限制请求频率, 此模块能通过特定的客户端标识(如IP,UA等)来限制客户端在一定时间内的访问频次;
如果是一瞬间的并发访问,那么我们就需要限制一秒之内的并发连接数,此时就需要用到第一个配置,如果一个IP疯狂的调用接口,如:页面上写个for循环一直刷请求,可能导致将服务器的带宽耗尽,此时就需要用到第二个配置
一、 ngx_http_limit_conn_module 模块
限制并发连接数
Syntax: | limit_conn_zone key zone=name:size; |
---|---|
Default: | — |
Context: | http |
Syntax: | limit_conn zone number; |
---|---|
Default: | — |
Context: | http, server, location |
一、ngx_http_limit_req_module 模块
limit_req_zone 和 limit_req
首先来看一下limit_req_zone的配置,该指令必须放置在http的范围内配置;
Syntax: | limit_req_zone $variable zone = name : size rate = rate |
Default: | |
Context: | http |
示例: limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
如上配置,
第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量;
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的写法,,即每2秒才处理一个请求。
最终NGINX会把所有的参数统一为按秒为单位。所以10r/s和600r/m效果是一样的
指令limit_req
Syntax: | limit_req zone = name [ burst = number ] [ nodelay ] |
Default: | |
Context: |
http server location |
示例:limit_req zone=one burst=5 nodelay;
如上配置,
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区
当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队
-
limit_req zone=req_zone;
- 严格依照在limti_req_zone中配置的rate来处理请求
- 超过rate处理能力范围的,直接drop
- 表现为对收到的请求无延时
-
limit_req zone=req_zone burst=5;
- 依照在limti_req_zone中配置的rate来处理请求
- 同时设置了一个大小为5的缓冲队列,在缓冲队列中的请求会等待慢慢处理
- 超过了burst缓冲队列长度和rate处理能力的请求被直接丢弃
- 表现为对收到的请求有延时
-
limit_req zone=req_zone burst=5 nodelay;
- 依照在limti_req_zone中配置的rate来处理请求
- 同时设置了一个大小为5的缓冲队列,当请求到来时,会爆发出一个峰值处理能力,对于峰值处理数量之外的请求,直接丢弃
- 在完成峰值请求之后,缓冲队列不能再放入请求。如果rate=10r/m,且这段时间内没有请求再到来,则每6 s 缓冲队列就能回复一个缓冲请求的能力,直到回复到能缓冲5个请求位置。
三、实列配置:
http { ## 这里取得原始用户的IP地址,没走CDN/SLB的,给到$remote_addr map $http_x_forwarded_for $clientRealIp { $remote_addr; default $http_x_forwarded_for; } #设置IP白名单,对内部的IP不设限 map $clientRealIp $limitIp{ default $clientRealIp; xx.xx.xx.xx ""; } limit_conn_status 429; limit_conn_zone $limitIp zone = myConnLimit : 10m; limit_conn_log_level notice; #限制请求数,并返回429状态; limit_req_status 429; limit_req_zone $limitIp zone=myReqLimit:10m rate=1r/s; #限制每秒一个请求 limit_req_log_level notice; server { location & nbsp; ^ ~ / download / { limit_conn myConnLimit 2; #一瞬间访问的时候,只会有2个IP能得到响应,后面的IP直接就返回503状态。 limit_req zone=myReqLimit burst=5 delay; } } }