例如,我们的网站暴露在公共网络环境中。除了正常的用户访问外,网络爬虫、恶意攻击、大额销售等突发流量也可能给系统带来压力。如果这种压力超过服务器的处理能力,就会导致响应缓慢甚至系统崩溃。
因此,当并发请求数过大时,我们通过限制部分请求(如限制同一IP的频繁请求)来保证服务器能够正确响应另一部分请求。
nginx提供了两种限流方式,一种是限制请求速率,一种是限制连接数。
还提供了下载/上传速度的限制。
2、限制请求速率
nginx的ngx_http_limit_req_module模块提供了限制请求处理速率的能力,使用漏桶算法。我们可以想象一个水桶,水从顶部流入,水从底部以恒定的速度流出。如果桶里有水,刚刚进入的水就会储存在桶里,直到下面的水喝完。速度快的话,桶里的水就满了。这时水不会进入桶内,而是直接从桶顶溢出。
对应于处理网络请求,水代表来自客户端的请求,桶代表一个队列,其中请求按照先进先出(FIFO)算法等待处理。泄漏意味着请求离开缓冲区并由服务器处理,溢出意味着请求被丢弃并且永远不会得到服务。
图片
2.1、正常限流
nginx中有两个主要指令可以用来配置限流:limit_req_zone和limit_req。
下面是最简单的限流例子:
limit_req_zone $binary_remote_addr znotallow=test:10m 速率=2r/s;服务器{ 位置/{ limit_req znotallow=test; }}imit_req_zone用于设置限流和共享内存区域的参数,格式为:limit_req_zone关键区域速率。
key:定义限流对象。 $binary_remote_addr是nginx中的一个变量,表示限流是基于remote_addr(客户端IP)。 binary_ 是二进制存储。使用$binary_remote_addr 而不是$remote_addr,因为二进制存储可以压缩内存占用。 $remote_addr 变量的大小从7 到15 个字节不等,而$binary_remote_addr 变量的大小对于IPv4 地址始终为4 字节,对于IPv6 地址始终为16 字节。 zone:定义一个共享内存区域,用于存储访问信息,包括每个IP地址的状态以及访问受限请求URL的频率。 zone的定义分为两部分:由znotallow=关键字标识的zone名称,以及冒号后的zone大小。 test:10m代表一块内存区域,大小为10M,名称为test。 1M可存储16000个IP地址的访问信息,测试可存储约16万个地址。当nginx创建新记录时,它会删除过去60秒内未使用的记录。如果释放的空间仍然无法存储新记录,则会返回503状态码。速率:设置最大访问速率。 rate=2r/s(为了更好的模拟,将rate设置为较小的值),表示每秒最多可以处理2个请求。事实上,nginx 以毫秒粒度跟踪请求。 Rate=2r/s 实际上是每500 毫秒1 个请求。也就是说,前一个请求完成后,如果500毫秒内还有请求到达,这些请求就会被处理。拒绝(默认返回503,如果想修改返回值,可以设置limit_req_status)。 limit_req_zone仅设置限流参数。如果要生效,必须与limit_req配合使用。 limit_req的格式为:limit_req znotallow=name [burst=number] [nodelay]。
上面的例子只是简单的指定了znotallow=test,表示测试区的配置用于请求html文件时进行限流。我们可以理解,这个桶目前没有任何存储水滴的能力,所有到达的不能立即泄漏的请求都会被拒绝。如果我在1秒内发送10个请求,其中前500毫秒1个,后500毫秒9个,那么只有前500毫秒的请求和后500毫秒的第一个请求会响应,其余的请求将被拒绝。
图片
2.2、处理突发流量
上述配置保证了nginx以固定的速度(2r/s)提供服务,但是这种情况不适合突发流量的情况。我们希望尽可能缓存请求并处理它们。这时,我们需要在limit_req中添加burst参数:
limit_req_zone $binary_remote_addr znotallow=test:10m 速率=2r/s;服务器{ 位置/{ limit_req znotallow=测试突发=5; }}burst表示超过设定的访问速率后可以处理的额外请求数。当rate=2r/s时,表示每500ms可以处理一个请求。当burst=5时,如果同时有10个请求到达,nginx会处理第一个请求,剩下的9个请求中的5个会放入队列,剩下的4个请求会直接被拒绝。然后每隔500ms从队列中获取一个请求进行处理。这时,如果后面有更多的请求进来,如果队列中的请求数量超过5,就会被拒绝。如果队列中的请求数小于5,则将其添加到队列中等待。我们可以理解为当前的水桶可以存放5滴水:
图片
配置burst后,虽然所有同时到达的请求都不会被拒绝,但仍然需要等待500ms的处理时间。放入桶中的第五个请求需要等待500ms * 4 才能处理。等待时间越长,就意味着用户的流失。在很多情况下,这个等待时间是不可接受的。这时候我们需要添加nodelay参数,并与burst配合使用。
limit_req_zone $binary_remote_addr znotallow=test:10m 速率=2r/s;服务器{ 位置/{ limit_req znotallow=测试突发=5 nodelay; }}nodelay 意味着没有延迟。设置nodelay后,第一个到达的请求以及队列中的请求都会立即处理,不会有等待的请求。
图片
需要注意的是,虽然队列中的5个请求是立即处理的,但队列中的位置仍然以500ms的速度顺序释放。接下来的四个请求仍然被拒绝,从长远来看这不会增加吞吐量的上限。长期吞吐量的上限由设定的速率决定。
2.3、设置白名单
如果遇到不需要限流的情况,比如为了测试压力测试,可以通过配置白名单的方式取消限流设置。白名单需要nginx的ngx_http_geo_module和ngx_http_map_module模块。
地理$限制{默认1; 10.0.0.0/8 0; 192.168.0.0/24 0;}映射$limit $limit_key { 0 ''; 1 $binary_remote_addr;}limit_req_zone $limit_key znotallow=mylimit:10mrate=2r/s;geo 该指令可以根据IP创建变量$limit。 $limit默认值为1,如果匹配到下面的IP,则返回对应的值(这里返回0)。
然后使用map命令将$limit的值映射到$limit_key:如果在白名单中,$limit_key为空字符串,如果不在白名单中,则为$binary_remote_addr。当limit_req_zone 指令的第一个参数为空字符串时,限制不起作用,因此列入白名单的IP 地址(在10.0.0.0/8 和192.168.0.0/24 子网中)不受限制,所有其他IP 地址都受到限制限制为2r/s
2.4、limit_req重复
如果在同一位置下配置了多个limit_req 指令,则将使用这些指令定义的限制。
地理$限制{默认1; 10.0.0.0/8 0; 192.168.0.0/24 0;}映射$limit $limit_key { 0 ''; 1 $binary_remote_addr;}limit_req_zone $limit_key znotallow=mylimit:10m 速率=2r/s;limit_req_zone $binary_remote_addr znotallow=myLimit2:10m 速率=10r/s;服务器{ 位置~* \.(html)$ { limit_req znotallow=mylimitburst=5 nodelay; limit_req znotallow=myLimit2 突发=5 nodelay; }}上面的示例配置了两个节点Rules,myLimit 和myLimit2。白名单用户虽然不符合mylimit规则,但根据规则mylimit2限制为10r/s。对于不在白名单中的用户,mylimit和mylimit2都需要匹配,两者中最严格的条件2r/s才会生效。
3、限制连接数
nginx的ngx_http_limit_conn_module模块提供了限制连接数的能力。包含limit_conn_zone和limit_conn两条指令,格式为limit_conn_zone key zone。
limit_conn_zone $binary_remote_addr znotallow=perip:10m;limit_conn_zone $server_name znotallow=perserver:10m;服务器{ 位置~* \.(html)$ { limit_conn perip 10; limit_conn 每台服务器100; }}limit_conn perip 10:key为$binary_remote_addr,表示单个限制IP同时最多可以容纳10个连接。 limit_conn perserver 100:关键是$server_name,表示该虚拟主机(服务器)同时可以处理的并发连接总数为100。需要注意的是,这个连接只有在请求头加上之后才算由后端服务器处理。
4、上传/下载速率限制
limit_rate主要用于限制用户和服务器之间传输的字节数。最常用的场景可能是下载/上传速度限制。 limit_rate没有单独的模块,而是在ngx_http_core_module中。同时它的相关指令也比较少,只有limit_rate和limit_rate_after。
4.1、limit_rate
服务器{ 位置/{ limit_rate 4k; limit_rate 的用法非常简单。后面的速率是特定的限速阈值。注意,默认单位是bytes/s,是每秒传输的字节数,而不是Bytes。比特率的位数可以设置为变量,从而可以实现动态限速。限速指令的有效范围是根据每个连接来确定的。比如每个连接的速率限制在4k以上,即客户端发起两个连接时。速率可以变成8k
4.2、limit_rate_after
server { location/{ limit_rate_after 500k;限制速率4k; }}limit_rate_after 允许在传输部分数据后进行速度限制。例如,在上述配置中,前500k数据传输不限速,500k之后将实施限速。比较常见的应用场景包括分段下载限速,对超过指定大小的部分进行速度限制;或者流媒体视频网站为了保证用户体验,保证能够尽快下载,一般不会限制首屏速度。加载出来,然后在用户开始观看视频后将带宽限制在合理的范围内,从而减少因客户端网速过快而提前加载过多内容而带来的额外成本。
4.3、proxy_limit_rate
proxy_limit_rate的基本原理和用法与limit_rate几乎相同。唯一的区别是proxy_limit_rate 限制nginx 与后端上游服务器之间的连接速率,而limit_rate 限制nginx 与客户端之间的连接速率。需要注意的是,proxy_limit_rate需要启用proxy_buffering命令才能生效。
#Syntax: Syntax: proxy_limit_rate rates;Default: proxy_limit_rate 0;Context: http, server, location该指令出现在版本1.7.7中。
4.4、动态限速
limit_rate的一大特点是可以使用变量,这意味着结合地图指令等可以实现动态限速功能。这里仅进行一些简单的演示。
4.4.1、基于时间动态限速
这里介绍一个nginx内置的ssi模块。该模块有两个有趣的时间变量:$date_local和$date_gmt,分别对应当前时间和GMT时间。
这里我们使用变量和map指令的组合,用正则表达式匹配不同的时间段,然后结合map变量将不同限速的不同时间段结合起来。
地图$date_local $limit_rate_time { 默认4K; ~(00:|01:|02:|03:|04:|05:|06:|07:).*:* 16K; (08:|12:|13:|18:).*:*8K; (19: | 20: | 21: | 22: | 23:)。* :* 16K; } limit_rate $limit_rate_time
4.2、基于变量动态限速
某些服务可能对未使用的用户有不同的速度限制。例如VIP用户的速度更快。例如,以下可以限制不同cookie的速度。
各位老铁们好,相信很多人对如何高效精准限制网站流量?Nginx配置指南都不是特别的了解,因此呢,今天就来为大家分享下关于如何高效精准限制网站流量?Nginx配置指南以及的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/6426.html
用户评论
刚学到 Nginx 配置,这篇文章应该很有帮助!
有7位网友表示赞同!
好文章啊,一直想学习怎么优化网站性能,这个能让我提升不少。
有10位网友表示赞同!
看标题就感觉很专业,需要好好研读下这本书的技巧。
有12位网友表示赞同!
流量限制确实是个热门问题, Nginx 能做的真多!
有10位网友表示赞同!
想要精通 Nginx ,这个资源肯定不可错过!
有5位网友表示赞同!
51CTO 的文章质量一直比较高,值得信赖。
有5位网友表示赞同!
这个标题直接点明了重点,我喜欢这种清晰的文章风格。
有9位网友表示赞同!
想学习一下高效精准的流量限制策略,来瞅瞅这篇文章吧!
有19位网友表示赞同!
精通 Nginx 真是个很棒的目标,以后要努力学习!
有18位网友表示赞同!
文章内容应该很详细,可以学到很多实战技巧。
有20位网友表示赞同!
好像有很多网站都用 Nginx 做代理服务器的哦!
有14位网友表示赞同!
流量控制很重要,特别是对于高流量网站来说更关键!
有14位网友表示赞同!
学习了 Nginx 的配置方法,以后可以自己优化网站性能了!
有14位网友表示赞同!
最近准备部署自己的网站,看看这篇文章能不能帮助我。
有6位网友表示赞同!
精通 Nginx 配置是 IT 领域的必备技能之一。
有18位网友表示赞同!
希望能在这个文章里学到一些解决实际问题的技巧。
有5位网友表示赞同!
想了解一下流量限制策略的具体执行步骤。
有11位网友表示赞同!
希望这篇文章能提供一些实用的案例分析。
有12位网友表示赞同!