Nginx 限流方法

运维猿 2018-10-23 17:25:31

限流(rate limiting)是Nginx众多特性中最有用的,也是经常容易被误解和错误配置的,特性之一。该特性可以限制某个用户在一个给定时间段内能够产生的HTTP请求数。请求可以简单到就是一个对于主页的GET请求或者一个登陆表格的POST请求。

限流可以用于安全目的上,通过限制请求速度来防止外部暴力扫描,或者减慢暴力密码破解攻击,可以结合日志标记出目标URL来帮助防范DDoS攻击,也可以解决流量突发的问题(如整点活动),一般地说,限流是用在保护上游应用服务器不被在同一时刻的大量用户请求湮没。

我们在访问内部域名时在1s时间内发起两个请求,操作上的一些时差会出现两种不同的结果,2个请求都返回200,或者1个请求返回200,而另外一个请求返回503,为此对Nginx限流模块进行了深入调研,Nginx在处理请求的时候是在1s内对请求的具体个数做拆分的,以2request/s为例,拆分为500ms内处理一个请求,下一个500ms才会处理第二个请求;除此之外,我们发现,在限制2request/s后,发现发送多个请求(requests>=2)也可以被处理掉,在此基础上上,调研了缓冲队列的相关配置。

1

漏桶和令牌桶算法的概念

漏桶算法(Leaky Bucket):主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。漏桶算法的示意图如下图所示,请求先进入到漏桶里,漏桶以一定的速度出水,当水请求过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

令牌桶算法(Token Bucket):是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。令牌桶算法示意图如下图所示,大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小。

2

两种算法的区别

两者主要区别在于“漏桶算法”能够强行限制数据的传输速率,而“令牌桶算法”在能够限制数据的平均传输速率外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,所以它适合于具有突发特性的流量。

3

按请求速率限速

按请求速率限速是指限制IP发送请求的速率,超出指定速率后,Nginx将直接拒绝更多的请求。采用漏桶算法实现。下面从一些实验数据上来深入的了解这个模块,先简单介绍一下该模块的配置方式,如下图所示(配置需要在Nginx配置和域名配置里面同时修改),使用limit_req_zone关键字,定义一个名为tip大小为10MB的共享内存区域(zone),用来存放限速相关的统计信息,限速的key值为二进制的IP地址($binary_remote_addr),限速上限(rate)为2r/s。

将上述规则应用到/search目录(单个IP的访问速度被限制在了2请求/秒,超过这个限制的访问将直接被Nginx拒绝)。burst和nodelay的作用稍后解释。(zone=tip:10m表示会话空间的存储大小为10m)。

4

3个实验案例

实验1、讨论2个请求在1s内的执行过程

修改配置下图所示:

我们使用ab工具模拟1s发送2个请求。

只有一个请求成功了,查看了一下执行时间:

1ms内完成了所有请求,考虑到每秒两个请求可能是分时间段来来完成的,二分法做了大量延迟处理的尝试,当两个请求之间的时延大于0.5s时第二个请求才会成功。

结论:Nginx的限流统计是基于毫秒的,我们设置的速度是2r/s,转换一下就是500ms内单个IP只允许通过1个请求,从501ms开始才允许通过第二个请求。

实验2、burst允许缓存处理突发请求

如果短时间内发送了大量请求,Nginx按照毫秒级精度统计,超出限制的请求直接拒绝。这在实际场景中未免过于苛刻,真实网络环境中请求到来不是匀速的,很可能有请求“突发”的情况。Nginx考虑到了这种情况,可以通过burst关键字开启对突发请求的缓存处理,而不是直接拒绝。(类似令牌桶算法)

修改Nginx配置如下:

我们加入了burst=4,意思是每个key(此处是每个IP)最多允许4个突发请求的到来。使用ab工具发送6个请求,结果会怎样呢?

发送时间:

执行结果是请求全部被处理,加入缓冲队列后,按照之前时间轴的规则 ,在0.001s、0.501s、1.001s、1.501s、2.001s、2.501s分别发送一个请求,与之前的有些偏差,理论上数据应该是同时发送到ngnix,我们做了抓包统进行验证,可以观察到6个请求分别开辟了6个端口进行发送,只有当第一个包三次握手完成,第二个包才开始发送,时间间隔500ms,这就验证了ab工具确实是单个发送的。

另外,理论上缓冲区之外的2个请求应该只有一个是200,另外一个是503,缓冲区的4个请求是按照2r/s的速度依次处理,这里是由于ab工具本身的问题,在加入缓冲队列后,发送时间由之前的1ms内完成变成了2501ms完成,所以导致了请求都被处理掉,若是使用其他工具短时间内发送6个请求,则只能成功5个。

发送耗时2ms,完成处理时间2437ms,每个请求的处理时间。

由于ngnix 500ms处理完第一个请求后,501ms才会处理第二个请求,所以5个请求(去掉503那个)耗时500ms*4+416ms=2416ms(本地实测,不同Nginx性能有所差异),或者使用ab工具并发来处理这些请求,也会有同样的效果。

我们再来观察一下发送时间,所有的请求基本在10ms内发起,这样便导致了6个请求中,去掉第一个和缓冲区的4个,第二个被拒绝掉。

实验3、nodelay降低排队时间

通过设置burst参数,我们可以允许Nginx缓存处理一定程度的突发,多余的请求可以先放到队列里,慢慢处理,这起到了平滑流量的作用。但是如果队列设置的比较大,请求排队的时间就会比较长,这对用户很不友好。nodelay参数允许请求在排队的时候就立即被处理,也就是说只要请求能够进入burst队列,就会立即被后台worker处理。

延续实验2的配置,我们加入nodelay选项:

同样发送6个请求发送时间:

实验结果如下图所示:

处理时间:

与实验2相比直观上的效果就是Nginx同时出现6条日志,即6个请求是同时被处理的,而实验2日志是逐条生成的,间隔0.5s,视觉上有卡顿。

虽然设置burst和nodelay能够降低突发请求的处理时间,但是长期来看并不会提高吞吐量的上限,长期吞吐量的上限是由rate决定的,因为nodelay只能保证burst的请求被立即处理,加入了nodelay参数之后的限速算法还算是漏桶算法,当令牌桶算法的token为耗尽时,由于它有一个请求队列,所以会把接下来的请求缓存下来,缓存多少受限于队列大小。假如server已经过载,缓存队列越来越长,即使过了很久请求被处理了,对用户来说也没什么价值了。所以当token不够用时,最明智的做法就是直接拒绝用户的请求,即漏桶算法


作者:Darren

QQ:603026148

以上内容归Darren所有,如果有什么错误或者不足的地方请联系我,希望我们共同进步。


Nginx 限流方法相关推荐

  1. NGINX限流的一些思考

    来源:http://blog.csdn.net/soar_away/article/details/51980247 我们经常遇到这种情况, 服务器资源有限,但是客户端来的请求在不断的上涨, 为了保证 ...

  2. 一文搞懂Nginx限流(简单实现)

    Nginx现在已经是最火的负载均衡之一,在流量陡增的互联网面前,接口限流也是很有必要的,尤其是针对高并发的场景.Nginx的限流主要是两种方式:限制访问频率和限制并发连接数. 限流(rate limi ...

  3. Nginx源码研究之nginx限流模块详解

    这篇文章主要介绍了Nginx源码研究之nginx限流模块详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 高并发系统有三把利器:缓存.降级和限流: 限流的目的是通过对并 ...

  4. sql server 配置管理器里为什么是32位_死磕 Nginx 系列:Nginx 限流配置

    点击上方 Java后端,选择 设为星标 优质文章,及时送达 限流算法:令牌桶算法 算法思想是: 令牌以固定速率产生,并缓存到令牌桶中: 令牌桶放满时,多余的令牌被丢弃: 请求要消耗等比例的令牌才能被处 ...

  5. nginx 限流,以及nginx直接返回json格式数据

    2019独角兽企业重金招聘Python工程师标准>>> 高并发系统有三把利器用来保护系统:缓存.降级和限流 今天我们这里说说限流.一般会在应用层配合redis做限流策略,这里我们聊聊 ...

  6. nginx限流以及配置管理

    nginx限流以及配置管理 nginx限流 限制并发连接数 http状态码 限制相同客户端的访问频次 burst nodelay limit_rate限制带宽 nginx配置管理 自动索引 expir ...

  7. 高并发解决方案之“Nginx限流”

    本文将分4个步骤讲解: 1.api压力测试 2.查看api响应性能 3.nginx限流进行优化 4.查看优化结果 1 api压力测试 1.1 安装压测工具 yum -y install httpd-t ...

  8. Nginx限流模块limit_req_zone、limit_req_conn

    根据nginx官网提供的说法,有两种算法,一种是漏桶算法,一种是令牌桶算法. limit_req_zone 用来限制单位时间内的请求数目,以及速度限制. limit_req_conn 用来限制同一时间 ...

  9. 实战:使用Nginx限流

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:深入浅出大型网站架构设计 Nginx不仅可以做Web服务器. ...

最新文章

  1. WEB前端:浏览器(IE+Chrome+Firefox)常见兼容问题处理【03】
  2. 论“性能需求分析”系列专题(一)之 性能需求剖析
  3. Oracle 11g R2手动配置EM(转)
  4. 代理服务器https协议单站点开通注意事项
  5. JavaFX官方教程(四)之Hello World,JavaFX样式
  6. java端到端_Java应用程序性能监控:复杂分布式应用程序的端到端性能
  7. java 参数命名冲突_Java中的命名参数
  8. js将百度坐标转为wgs84
  9. Mac中使用svn进行项目管理
  10. Ceres-Solver库入门
  11. Visual Studio 2010全球发布会 上海站(图)
  12. 软中断和tasklet
  13. UnityWebPlayer缓存清理工具
  14. 历届美国梦之队战斗力汇总:梦一无敌 梦十二平淡
  15. 发现数字财富的秘密之三:60分钟搞清楚数字技术ABC|链塔智库
  16. R语言基本用法(主要为时间序列分析方面)
  17. python--手机步数----微信运动--支付宝运动等步数刷新
  18. HTML+CSS静态页面网页设计作业——我的家乡-四川成都(4页) HTML+CSS+JavaScript
  19. 谁在用生命为错误买单?
  20. 《王者荣耀》皮肤个性动作涉嫌抄袭

热门文章

  1. google colab代码自动补全快捷键设置
  2. cocos2d-x自制RPG游戏总结
  3. [绍棠] 升级Xcode10和Xcode11问题集
  4. uniapp 页面禁止按物理按键返回
  5. 微信小程序--云函数部署问题
  6. c语言编译系统的搭建,云服务器搭建c语言编译环境
  7. js水平无缝滚动代码实例详解
  8. 阿里云服务器备份从快照到自定义镜像再将镜像导出保存下载到本地
  9. 原生JDBC连接步骤
  10. The label does not denote a loop in forEach