限流配置-葵花宝典!一文搞定-Nginx (限流模式)

教程大全 2025-07-18 05:36:07 浏览
漏桶算法

算法思想是:

从作用上来说,漏桶和令牌桶算法最明显的区别就是是否允许突发流量(burst)的处理,漏桶算法能够强行限制数据的实时传输(处理)速率,对突发流量不做额外处理;而令牌桶算法能够在限制数据的平均传输速率的同时允许某种程度的突发传输。

Nginx按请求速率限速模块使用的是漏桶算法,即能够强行保证请求的实时处理速度不会超过设置的阈值。

Nginx官方版本限制IP的连接和并发分别有两个模块:

limit_req_zone 参数配置

Syntax:limit_reqzone=name[burst=number][nodelay];Default:—Context:HTTP,Server,location

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

limit_req zone=one burst=5 nodelay;

例子

http{limit_req_zone$binary_remote_addrzone=one:10mrate=1r/s;server{location/search/{limit_reqzone=oneburst=5nodelay;}}

下面配置可以限制特定UA(比如搜索引擎)的访问:

limit_req_zone$anti_spiderzone=one:10mrate=10r/s;limit_reqzone=oneburst=100nodelay;if($http_user_agent~*"googlebot|bingbot|Feedfetcher-Google"){set$anti_spider$http_user_agent;}

其他参数

Syntax:limit_req_log_levelinfo|notice|warn|error;Default:limit_req_log_levelerror;Context:http,server,location

服务器 由于limit被限速或缓存时,配置写入日志。延迟的记录比拒绝的记录低一个级别。例子: limit_req_log_level notice 延迟的的基本是info。

Syntax:limit_req_statuscode;Default:limit_req_status503;Context:http,server,location

设置拒绝请求的返回值。值只能设置 400 到 599 之间。

ngx_http_limit_conn_module 参数配置

这个模块用来限制单个IP的请求数。并非所有的连接都被计数。只有在服务器处理了请求并且已经读取了整个请求头时,连接才被计数。

Syntax:limit_connzonenumber;Default:—Context:http,server,location
limit_conn_zone$binary_remote_addrzone=addr:10m;server{location/download/{limit_connaddr1;}

一次只允许每个IP地址一个连接。

limit_conn_zone$binary_remote_addrzone=perip:10m;limit_conn_zone$server_Namezone=perserver:10m;server{...limit_connperip10;limit_connperserver100;}

可以配置多个limit_conn指令。例如,以上配置将限制每个客户端IP连接到服务器的数量,同时限制连接到虚拟服务器的总数。

Syntax:limit_conn_zonekeyzone=name:size;Default:—Context:http
limit_conn_zone$binary_remote_addrzone=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_levelinfo|notice|warn|error;Default:limit_conn_log_levelerror;Context:http,server,location

当服务器限制连接数时,设置所需的日志记录级别。

Syntax:limit_conn_statuscode;Default:limit_conn_status503;Context:http,server,location

设置拒绝请求的返回值。

2、实战

实例一 限制访问速率

limit_req_zone$binary_remote_addrzone=mylimit:10mrate=2r/s;server{location/{limit_reqzone=mylimit;}}

上述规则限制了每个IP访问的速度为2r/s,并将该规则作用于根目录。如果单个IP在非常短的时间内并发发送多个请求,结果会怎样呢?

单个IP 10ms内发送6个请求

我们使用单个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_addrzone=mylimit:10mrate=2r/s;server{location/{limit_reqzone=mylimitburst=4;}}

我们加入了burst=4,意思是每个key(此处是每个IP)最多允许4个突发请求的到来。如果单个IP在10ms内发送6个请求,结果会怎样呢?

设置burst

相比实例一成功数增加了4个,这个我们设置的burst数目是一致的。具体处理流程是:1个请求被立即处理,4个请求被放到burst队列里,另外一个请求被拒绝。通过burst参数,我们使得Nginx限流具备了缓存处理突发流量的能力。

但是请注意:burst的作用是让多余的请求可以先放到队列里,慢慢处理。如果不加nodelay参数,队列里的请求不会立即处理,而是按照rate设置的速度,以毫秒级精确的速度慢慢处理。

实例三 nodelay降低排队时间

实例二中我们看到,通过设置burst参数,我们可以允许Nginx缓存处理一定程度的突发,多余的请求可以先放到队列里,慢慢处理,这起到了平滑流量的作用。但是如果队列设置的比较大,请求排队的时间就会比较长,用户角度看来就是RT变长了,这对用户很不友好。有什么解决办法呢?nodelay参数允许请求在排队的时候就立即被处理,也就是说只要请求能够进入burst队列,就会立即被后台worker处理,请注意,这意味着burst设置了nodelay时,系统瞬间的QPS可能会超过rate设置的阈值。nodelay参数要跟burst一起使用才有作用。

延续实例二的配置,我们加入nodelay选项:

limit_req_zone$binary_remote_addrzone=mylimit:10mrate=2r/s;server{location/{limit_reqzone=mylimitburst=4nodelay;}}

单个IP 10ms内并发发送6个请求,结果如下:

设置burst和nodela

跟实例二相比,请求成功率没变化,但是总体耗时变短了。这怎么解释呢?实例二中,有4个请求被放到burst队列当中,工作进程每隔500ms(rate=2r/s)取一个请求进行处理,最后一个请求要排队2s才会被处理;实例三中,请求放入队列跟实例二是一样的,但不同的是,队列中的请求同时具有了被处理的资格,所以实例三中的5个请求可以说是同时开始被处理的,花费时间自然变短了。

但是请注意,虽然设置burst和nodelay能够降低突发请求的处理时间,但是长期来看并不会提高吞吐量的上限,长期吞吐量的上限是由rate决定的,因为nodelay只能保证burst的请求被立即处理,但Nginx会限制队列元素释放的速度,就像是限制了令牌桶中令牌产生的速度。

看到这里你可能会问,加入了nodelay参数之后的限速算法,到底算是哪一个“桶”,是漏桶算法还是令牌桶算法?当然还算是漏桶算法。考虑一种情况,令牌桶算法的token为耗尽时会怎么做呢?由于它有一个请求队列,所以会把接下来的请求缓存下来,缓存多少受限于队列大小。但此时缓存这些请求还有意义吗?如果server已经过载,缓存队列越来越长,RT越来越高,即使过了很久请求被处理了,对用户来说也没什么价值了。所以当token不够用时,最明智的做法就是直接拒绝用户的请求,这就成了漏桶算法。

示例四 自定义返回值

limit_req_zone$binary_remote_addrzone=mylimit:10mrate=2r/s;server{location/{limit_reqzone=mylimitburst=4nodelay;limit_req_status598;}}
限流配置

默认情况下 没有配置 status 返回值的状态:

没有配置 status

自定义 status 返回值的状态:

自定义返回值

电路高手帮忙分析下这个扩流电路

很简单的一个电路啊,如下:317的功能是一个三端稳压器件,在这里当然是用来稳定输出电压的啊,其adj脚到output脚的电压为1.25V。 VR1用来调节输出电压的(使用时注意满足 Vin-min=Vdrop+Vadj+VL ,Vdrop是317的内部压降,一般为2v左右,Vadj是三端器件的内部参考电压,为1.25V,VL就是我们负载的压降了)。 当R5的电流>1.25V/200R时,Q2(TIP32C)、Q1(2N3055)导通,负载支路的电流从 Vin流出,经Q1、并联的R3,R4 再经负载到电源地,形成功率回路。 这里的R3、R4是限流电阻,利用三极管8050C的b、e间的电压(0.6V左右)对功率回路进行限流,限流点为0.6V/0.11R,这个限流点就是该电路的最大输出电流。 明白么???

邮寄包裹需要什么??

目前的邮局邮寄有这几钟:EMS(特快专递),普通快递,普通慢件,印刷品邮寄,信件邮寄。 EMS(特快专递)这个是最快的,一般是3天左右就到了。 当然,它也是最昂贵的一种了!500克内的包裹是20元,然后每增加200克再增加6元,还有就是它把全国分为3区,1区的原价,2区的再加6元,3区的……加12!分区是按距离的远近算的!普通快递价格一般比慢件贵一半,但是实际效率呢,跟慢件差不多的……普通慢件这个上最便宜的了!一般500克内的东西不是太远的话基本5快钱搞定!当然,时间也需要的很长,比如,新疆的朋友寄到我这的包裹,大概15-20天我才能收到…… 一般最快也得5天左右!印刷品邮寄这个嘛,如果你是寄几本书的话,就用它吧,价格还可以,速度跟信件一样,优点是直接送到收件人手里,不需要跑邮局了!但是不可以查询,不过还可以使用挂号邮寄,就是多掏3快钱吧,变的可以查询了!信件邮寄这个……基本对包裹来说是没什么用吧,不过你可以用信件跟朋友,MM什么的聊聊,前提是你不嫌麻烦……不过这就不是要讨论的范围了:)最后总结,邮寄包裹最省钱的方法我现在教给大家,看仔细了:1,自己找个盒子,不要使用邮局提供的!因为邮局的盒子卖的太贵!则就可以找鞋盒子什么的,或者到商店里去买合适的盒子,基本1快钱搞定!2,不保价,因为邮局的包裹一般是不会丢失的,只要包的好,也不会搞出什么毛病的,所以,就没必要花费这个钱了:)保价费也是按保价金额的百分之1算的。 当然,我说的是一般情况,如果你太倒霉了,包裹丢失又没保价的话,可不要找我啊,呵呵。 做到以上2点,就能够省钱了,虽然一次不多,但是对于我这样常常邮寄的来说,就显的不少拉,起码上网费省下来拉:)。 另外,关于包裹包装的问题讲一下。 包裹一定要包结实,起码拿起来摇晃的时候不能有晃动的感觉,因为邮局的工作人员实在是太牛X了,都是向地上摔下去的,看的我是那个心惊肉跳啊!物品要用报纸包结实,如果有菠沫的话,就更好了,不但轻而且更安全!然后包装的外面用透明胶卷粘贴的密不透风最好,反正是邮局的,不用白不用:)!

改装农用电动独轮车速度太快怎么办

加个调速器!

本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐