Nginx限流配置-令牌桶算法

更新时间:2023-07-09 18:17:55 阅读: 评论:0

Nginx限流配置-令牌桶算法
算法思想是:
令牌以固定速率产⽣,并缓存到令牌桶中;
令牌桶放满时,多余的令牌被丢弃;
请求要消耗等⽐例的令牌才能被处理;
令牌不够时,请求被缓存。
漏桶算法
算法思想是:
⽔(请求)从上⽅倒⼊⽔桶,从⽔桶下⽅流出(被处理);
来不及流出的⽔存在⽔桶中(缓冲),以固定速率流出;
⽔桶满后⽔溢出(丢弃)。
这个算法的核⼼是:缓存请求、匀速处理、多余的请求直接丢弃。
相⽐漏桶算法,令牌桶算法不同之处在于它不但有⼀只“桶”,还有个队列,这个桶是⽤来存放令牌的,队列才是⽤来存放请求的。
从作⽤上来说,漏桶和令牌桶算法最明显的区别就是是否允许突发流量(burst)的处理,漏桶算法能够强⾏限制数据的实时传输(处理)速率,对突发流量不做额外处理;⽽令牌桶算法能够在限制数据的平均传输速率的同时允许某种程度的突发传输。
Nginx按请求速率限速模块使⽤的是漏桶算法,即能够强⾏保证请求的实时处理速度不会超过设置的阈值。
Nginx官⽅版本限制IP的连接和并发分别有两个模块:
limit_req_zone ⽤来限制单位时间内的请求数,即速率限制,采⽤的漏桶算法 "leaky bucket"。
limit_req_conn ⽤来限制同⼀时间连接数,即并发限制。
limit_req_zone 参数配置
Syntax: limit_req zone=name [burst=number] [nodelay];
吴桐水Default: —
Context: http, rver, location
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
第⼀个参数:$binary_remote_addr 表⽰通过remote_addr这个标识来做限制,“binary_”的⽬的是缩写内存占⽤量,是限制同⼀客户端ip地址。
第⼆个参数:zone=one:10m表⽰⽣成⼀个⼤⼩为10M,名字为one的内存区域,⽤来存储访问的频次信息。
第三个参数:rate=1r/s表⽰允许相同标识的客户端的访问频次,这⾥限制的是每秒1次,还可以有⽐如
30r/m的。
limit_req zone=one burst=5 nodelay;
第⼀个参数:zone=one 设置使⽤哪个配置区域来做限制,与上⾯limit_req_zone ⾥的name对应。
第⼆个参数:burst=5,重点说明⼀下这个配置,burst爆发的意思,这个配置的意思是设置⼀个⼤⼩为5的缓冲区当有⼤量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。
第三个参数:nodelay,如果设置,超过访问频次⽽且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。
例⼦:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
rver {
location /arch/ {
limit_req zone=one burst=5 nodelay;
}
}
下⾯配置可以限制特定UA(⽐如搜索引擎)的访问:
limit_req_zone  $anti_spider  zone=one:10m  rate=10r/s;
limit_req zone=one burst=100 nodelay;
if ($http_ur_agent ~* "googlebot|bingbot|Feedfetcher-Google") {
t $anti_spider $http_ur_agent;
}
其他参数
Syntax: limit_req_log_level info | notice | warn | error;
Default:
limit_req_log_level error;
Context: http, rver, location
当服务器由于limit被限速或缓存时,配置写⼊⽇志。延迟的记录⽐拒绝的记录低⼀个级别。例⼦:limit_req_log_level notice延迟的的基本是info。
Syntax: limit_req_status code;
Default:
limit_req_status 503;快乐的理由
Context: http, rver, location
设置拒绝请求的返回值。值只能设置 400 到 599 之间。
ngx_http_limit_conn_module 参数配置
这个模块⽤来限制单个IP的请求数。并⾮所有的连接都被计数。只有在服务器处理了请求并且已经读取了整个请求头时,连接才被计数。
Syntax: limit_conn zone number;
Default: —
Context: http, rver, location
limit_conn_zone $binary_remote_addr zone=addr:10m;
rver {
location /download/ {
limit_conn addr 1;
}
⼀次只允许每个IP地址⼀个连接。
limit_conn_zone $binary_remote_addr zone=perip:10m;
赠贾岛limit_conn_zone $rver_name zone=perrver:10m;
rver {秋天的收获
...
limit_conn perip 10;
limit_conn perrver 100;
}
可以配置多个limit_conn指令。例如,以上配置将限制每个客户端IP连接到服务器的数量,同时限制连接到虚拟服务器的总数。
Syntax: limit_conn_zone key zone=name:size;
Default: —地理必修二
Context: http
limit_conn_zone $binary_remote_addr zone=addr:10m;
在这⾥,客户端IP地址作为关键。请注意,不是$ remote_addr,⽽是使⽤$ binary_remote_addr变量。 $ remote_addr变量的⼤⼩可以从7到15个字节不等。存储的状态在32位平台上占⽤32或64字节的内存,在64位平台上总是占⽤64字节。对于IPv4地址,$
binary_remote_addr变量的⼤⼩始终为4个字节,对于IPv6地址则为16个字节。存储状态在32位平台上始终占⽤32或64个字节,在64位平台上占⽤64个字节。⼀个兆字节的区域可以保持⼤约32000个32字节的状态或⼤约16000个64字节的状态。如果区域存储耗尽,服务器会将错误返回给所有其他请求。
Syntax: limit_conn_log_level info | notice | warn | error;
Default:
limit_conn_log_level error;
Context: http, rver, location
当服务器限制连接数时,设置所需的⽇志记录级别。
Syntax: limit_conn_status code;
Default:
limit_conn_status 503;鉴往知来
Context: http, rver, location
设置拒绝请求的返回值。
实战
实例⼀限制访问速率
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
rver {
location / {
limit_req zone=mylimit;
}
}
上述规则限制了每个IP访问的速度为2r/s,并将该规则作⽤于根⽬录。如果单个IP在⾮常短的时间内并发发送多个请求,结果会怎样呢?
我们使⽤单个IP在10ms内发并发送了6个请求,只有1个成功,剩下的5个都被拒绝。我们设置的速度是2r/s,为什么只有1个成功呢,是不是Nginx限制错了?当然不是,是因为Nginx的限流统计是基于毫秒的,我们设置的速度是2r/s,转换⼀下就是500ms内单个IP只允许通过1个请求,从501ms开始才允许通过第⼆个请求。
实例⼆ burst缓存处理
我们看到,我们短时间内发送了⼤量请求,Nginx按照毫秒级精度统计,超出限制的请求直接拒绝。这在实际场景中未免过于苛刻,真实⽹络环境中请求到来不是匀速的,很可能有请求“突发”的情况,也就是“⼀股⼦⼀股⼦”的。Nginx考虑到了这种情况,可以通过burst关键字开启对突发请求的缓存处理,⽽不是直接拒绝。
苏小美来看我们的配置:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
rver {
溶豆几个月宝宝可以吃location / {
limit_req zone=mylimit burst=4;
}
}
我们加⼊了burst=4,意思是每个key(此处是每个IP)最多允许4个突发请求的到来。如果单个IP在10ms内发送6个请求,结果会怎样呢?
相⽐实例⼀成功数增加了4个,这个我们设置的burst数⽬是⼀致的。具体处理流程是:1个请求被⽴即处理,4个请求被放到burst队列⾥,另外⼀个请求被拒绝。通过burst参数,我们使得Nginx限流具备了缓存处理突发流量的能⼒。
但是请注意:burst的作⽤是让多余的请求可以先放到队列⾥,慢慢处理。如果不加nodelay参数,队列⾥的请求不会⽴即处理,⽽是按照rate设置的速度,以毫秒级精确的速度慢慢处理。
实例三 nodelay降低排队时间
实例⼆中我们看到,通过设置burst参数,我们可以允许Nginx缓存处理⼀定程度的突发,多余的请求可以先放到队列⾥,慢慢处理,这起到了平滑流量的作⽤。但是如果队列设置的⽐较⼤,请求排队的时间就会⽐较长,⽤户⾓度看来就是RT变长了,这对⽤户很不友好。有什么解决办法呢?nodelay参数允许请求在排队的时候就⽴即被处理,也就是说只要请求能够进⼊burst队列,就会⽴即被后台worker处理,请注意,这意味着burst设置了nodelay时,系统瞬间的QPS可能会超过rate设置的阈值。nodelay参数要跟burst⼀起使⽤才有作⽤。
延续实例⼆的配置,我们加⼊nodelay选项:

本文发布于:2023-07-09 18:17:55,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1074726.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:MTK工程指令
标签:请求   限制   处理   设置   突发
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图