当前位置: 首页 > news >正文

Nginx的请求速率限制模块的两个关键参数rate和burst和相关代码语句的详细说明。

目录

  • 01-参考文章
  • 02-参数rate和burst的详细解释
  • 03-实际例子及代码详解
  • 04-rate值可不可以为小数?
  • 05-请求超过允许速率Nginx会提示什么?

01-参考文章

本文参考文章下面两篇文章写成(建议阅读前先看下下面两篇文章):
NGINX速率限制原理及源码分析
Nginx限速模块初探

02-参数rate和burst的详细解释

rate的单位是 r/s,单位直译过来是 次数/秒,即每秒内允许的最大请求次数。
常常发生的误解:比如 rate 的值为 5,那么这代表每秒内允许的最大请求数为5吗?
答案是:并不完全是每秒内允许的最大请求数为5。

如果你没有设置burst参数,并且你在200ms的范围内连续发起了5次请求,那么只有第1次请求会被执行,后面的4次都会被丢弃。具体的例子可参考文章:Nginx限速模块初探,这篇文章中有具体的例子。
为什么会这样?因为Nginx是在毫秒级别来执行请求的,因为1秒=1000毫秒,所以 5 r/s 代表的真正意义为 1 次/200毫秒,即每200毫秒执行一次请求。
所以其实 5 r/s 是定义了一个时间窗口,一个时间窗口的宽度可执行一次请求,在这个例子中,时间窗口的宽度为 200毫秒,即每200毫秒执行一次请求。

但实际情况是,经常会有200毫秒内超过1次请求的情况发生,此时怎么办呢?burst参数就起作用了。burst代表Nginx一次最多能接收多少个请求,请求数如果在burst的范围内,那么这些请求即使超过了1或超过了rate的数值,也能被Nginx安排到队列中。
burst有两种工作模式,一种是有delay的工作模式(burst的默认工作模式),一种是没有delay的工作模式,即nodelay的工作模式。
以rate = 5 r/s = 1 次/200毫秒,burst = 10 为例 来说明这个问题。
当处于delay的工作模式时:
这是burst的默认工作模式。假设客户端在短时间内(比如200毫秒内)发起了11次请求,那么此时Nginx会把前10次请求加入到burst的队列槽位中,把最后一次丢弃,然后每隔200毫秒执行一个请求,同时在处理期间每隔200毫秒释放掉一个队列槽位的占用,这个被释放掉的队列槽位可以新填入一个后续请求,然后后续请求依次被执行。
当处于nodelay的工作模式时:
同样假设客户端在短时间内(比如200毫秒内)发起了11次请求,此时Nginx也会把前10次请求加入到队列槽位中,把最后一次丢弃,然后在一个时间窗口单位时间内(即200毫秒内)把这10次请求全部执行完。请注意,虽然这10次请求全部执行完了,但是队列槽位的占用仍没被释放,而是每隔200毫秒,即一个时间窗口的单位释放一个队列槽位的占用,这个被释放掉的队列槽位可以新填入一个后续请求,然后后续请求依次被执行。

03-实际例子及代码详解

对应于上面两个参数的详解,例子的相应代码如下:

# 限速配置,限速配置需放在server块之外
limit_req_zone $binary_remote_addr zone=ip_limit_01s:10m rate=5r/s;
......
server {location / {# 限速配置limit_req zone=ip_limit_01s burst=10 nodelay;}
}

代码详解:

limit_req_zone $binary_remote_addr zone=ip_limit_01s:10m rate=5r/s;

在上述Nginx配置语句中,limit_req_zone 是一个用于配置基于客户端IP地址的请求速率限制的指令。

具体来说,这个指令用于定义一个请求限制区域(request zone),该区域将被用于存储有关客户端请求速率的信息。这个信息包括客户端的IP地址、请求计数等。这样,Nginx就能够跟踪每个客户端的请求频率,并根据预定义的速率进行限制。

让我们分解这个具体的例子:

  • $binary_remote_addr: 这是一个Nginx变量,表示客户端的二进制格式的IP地址。这是作为限制的依据,以便针对不同的客户端进行限制。除了$binary_remote_addr,Nginx 还提供了其他一些变量,可以作为请求速率限制的依据。以下是其中一些常见的变量:
  1. $binary_remote_addr: 客户端的二进制格式的IP地址。

  2. $remote_addr: 客户端的IP地址。

  3. $http_user_agent: 客户端的User-Agent头,表示客户端的浏览器、操作系统等信息。

  4. $server_name: 当前请求的服务器名。

  5. $host: 当前请求的Host头,用于标识请求的目标主机。

  6. $request_uri: 完整的请求URI,包括参数。

  7. $scheme: 请求的协议(http或https)。

  8. $http_referer: 表示引导用户代理到当前页的URI。

    你可以根据具体的需求选择合适的变量作为限制依据。例如,如果你想根据不同的User-Agent对请求进行速率限制,你可以使用$http_user_agent。在配置 limit_req_zone 指令时,只需将适当的变量替换到$binary_remote_addr的位置即可。
    提问:$binary_remote_addr$remote_addr有何区别?
    $binary_remote_addr$remote_addr 都是用于表示客户端的IP地址,但它们之间有一些区别:

    1. 数据格式:
      • $binary_remote_addr: 表示客户端IP地址的二进制格式。
      • $remote_addr: 表示客户端IP地址的文本格式。
    2. 用途:
      • $binary_remote_addr: 主要用于在 limit_req_zone 中作为限制区域的依据。由于是二进制格式,它在内存中的存储效率更高,适合用于大规模请求限制。
      • $remote_addr: 通常用于在日志中记录客户端的IP地址,或者在其他地方需要IP地址的文本表示时使用。
  • zone=ip_limit_01s:10m: 这部分定义了请求限制区域的名称(ip_limit_01s)和其最大大小(10m,即10兆字节)。名称会在后面配置具体的server块的限制请求数时使用到,限制区域的大小用于存储请求的状态信息。

  • rate=5r/s: 这个在本文前面我已经讲得很清楚、很具体了,这里就不再作过多说明了。

limit_req zone=ip_limit_01s burst=10 nodelay;

这句代码就没什么好讲的了。这句代码就是调用了上一句代码中定义的请求限制区域“ip_limit_01s”,然后把burst的队列槽位值设为10,并且以 nodelay 的模式运行。前面已经说得很清楚了,就没什么好说的了。

04-rate值可不可以为小数?

提问:Nginx的限制请求速率的模块中的rate值可不可以设置为小数? 比如 rate 可不可以为0.5?
答:不可以。应设置为整数。

05-请求超过允许速率Nginx会提示什么?

提问:如果超过请求允许速率,会发生什么情况?
答,会提示503错误,如下图所示:
在这里插入图片描述

相关文章:

  • 使用阿里巴巴同步工具DataX实现Mysql与ElasticSearch数据同步
  • Python学习笔记-类
  • neuq-acm预备队训练week 8 P1144 最短路计数
  • VC++使用GetProcessTimes获取进程创建时间、销毁时间、用户态时间、内核态时间
  • 20231207给NanoPC-T4(RK3399)开发板刷Android12的挖掘机方案的LOG
  • Global IIIumination(GI)全局光照原理(一)3D空间全局光照
  • 【计算机网络实验】实验三 IP网络规划与路由设计(头歌)
  • 三. LiDAR和Camera融合的BEV感知算法-BEVFusion实战
  • 聚类算法的性能度量
  • MFC CLXHHandleEngine动态库-自定义设置对话框使用
  • 【线性代数与矩阵论】Jordan型矩阵
  • http的 content-type都有哪些?
  • Centos7及Ubuntu系统安装指定版本dockerdocker-compose安装
  • 基于以太坊的智能合约开发Solidity(基础篇)
  • Leetcode—389.找不同【简单】
  • $translatePartialLoader加载失败及解决方式
  • @jsonView过滤属性
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • bootstrap创建登录注册页面
  • centos安装java运行环境jdk+tomcat
  • JavaScript新鲜事·第5期
  • Meteor的表单提交:Form
  • orm2 中文文档 3.1 模型属性
  • PHP 7 修改了什么呢 -- 2
  • Puppeteer:浏览器控制器
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 关于springcloud Gateway中的限流
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 那些被忽略的 JavaScript 数组方法细节
  • 如何用vue打造一个移动端音乐播放器
  • 使用parted解决大于2T的磁盘分区
  • 微信小程序设置上一页数据
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 优化 Vue 项目编译文件大小
  • 在Mac OS X上安装 Ruby运行环境
  • 正则表达式
  • C# - 为值类型重定义相等性
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #if #elif #endif
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (7) cmake 编译C++程序(二)
  • (C++)八皇后问题
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (搬运以学习)flask 上下文的实现
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (七)c52学习之旅-中断
  • (一)Java算法:二分查找
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模