
nginx可以通过limit_conn_zone 和limit_req_zone两个组件来对客户端访问目录和文件的访问频率和次数进行限制
指定一个会话的最大同时连接数limit_conn_zone
http {
limit_conn_zone $binary_remote_addr zone=one:10m;
............
server {
listen 80;
server_name www.abc.com;
location / {
limit_conn one 1; #这将指定一个地址只能同时存在一个连接。“one”与上面的对应,也可以自定义命名
limit_rate 300k;
}
}
limit_conn_zone: 是针对每个IP定义一个存储session状态的容器.这个示例中定义了一个10m的容器,按照32bytes/session, 可以处理320000个session。
limit_conn one 1:限制每个IP只能发起一个并发连接。
limit_rate 300k: 对每个连接限速300k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate×2。
限制访问频率 limit_req_zone
不管是:30r/m,5r/s,180r/m.....
所有的请求会自动转换为1秒内的请求并发数,即:30r/m->0.5r/s,180r/m->3r/s
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /search/ {
limit_req zone=one; //超过rate,就丢弃
limit_req zone=one burst=5 nodelay; //超过rate就加5缓冲列队,不阻塞,超出缓冲列队就丢弃
limit_req zone=one burst=5 ; //超过rate就加5缓冲列队,阻塞,超出缓冲就丢弃
}
}
zone=one:10m
客户端 IP 地址用作密钥。$remote_addr请注意, 此处使用的是变量,而不是$binary_remote_addr。对于 IPv4 地址,变量$binary_remote_addr的大小始终为 4 字节;对于 IPv6 地址,变量的大小始终为 16 字节。存储的状态在 32 位平台上始终占用 64 字节,在 64 位平台上始终占用 128 字节。1 MB 区域可以保存大约 16,000 个 64 字节状态或大约 8,000 个 128 字节状态。
$binary_remote_addr :表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址
zone=one:10m:表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
rate=1r/s:表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,即每秒只处理一个请求,还可以有比如30r/m的,即限制每2秒访问一次,即每2秒才处理一个请求。
zone=one :设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
burst=5:重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,但是这个等待区里的位置只有5个,超过的请求会直接报503的错误然后返回。
nodelay:
如果设置,会在瞬时提供处理(burst + rate)个请求的能力,请求超过(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况。(这里的rate的单位是:r/s)
如果没有设置,则所有请求会依次等待排队
burst
总结:
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 秒缓冲队列就能回复一个缓冲请求的能力,直到回复到能缓冲5个请求位置。