nginx 限速之limit_req

news/2024/12/12 6:31:30/

        nginx_http_limit_req_module用于限制定义key(单个ip)的请求的处理速度限制的方法如同漏斗,每秒固定处理请求数,推迟过多请求,如但客户端ip的每秒请求数.还可以用于安全防护,限制密码撞库暴力破解等操作频率,也可以通过把请求频率限制在一个正常范围来抵御ddos攻击,不过更常见的使用情况是通过限制请求的数量来确保后端的upstream服务器不会在短时间内遭受到大量的流量访问从而导致服务异常。

1. 工作原理

        nginx 中限速(rate limiting)的主要算法原理是漏斗算法:基本原理就是以漏斗算法,基本原理就是:以漏斗为例,水从顶部倒入,从底下漏出.

 在桶满后该算法有两种处理方式Traffic Shaping和Traffic Policing

1. 暂时拦截住上方水的向下流动,等待桶中的一部分水漏走后,再放行上方水。
2. 溢出的上方水直接抛弃。

        将水看作网络通信中数据包的抽象,则方式1起到的效果称为Traffic Shaping,方式2起到的效果称为Traffic Policing
        由此可见,Traffic Shaping的核心理念是"等待",Traffic Policing的核心理念是"丢弃"。它们是两种常见的流速控制方法
        漏斗在一定程度上代表服务器的处理能力,请求根据先进先出(FIFO)调度算法等待处理,若倒入的水的速度小于漏水的速度,可以理解为服务器能够处理完所有的请求,此时整体服务表现正常。如果倒入水的速度大于漏水的速度,那么水桶内的水会不断增加直到最后溢出,这种情况下在水桶中的水可以理解为在队列中等待的请求,而溢出的水则表示直接被丢弃不处理的请求。

2. limit_req_zone 指令

Syntax:  limit_req_zone key zone=name:size rate=rate;
Context: http
Defaule: - 

说明:

key:  使用nginx内置变量作为键,用于限制请求的变量,可以使用$binary_remote_addr,它的特点是使用二进制来表示IP地址,如1.1.1.1这个ip在$remote_addr中显示为1.1.1.1,$binary_remote_addr表示为二进制形式,因此$binary_remote_addr占用的空间要比$remote_addr更少.使用$binary_remote_addr意味着将每个唯一的用户ip作为心智速率的判断依据.

zone: 定义用于存储前面定义的key变量和限制其访问请求频率tate变量的共享内存空间,将信息保存在共享内存中的好处是能够在多个worker进程中共享。存储空间的定义由两个部分组成:zone=后面的名称以及冒号后面的大小,如zone=mylimit:10m 就是一个名为mylimit的大小为10m的共享内存空间。以$binary_remote_addr 变量为例,它使用4 bytes来存储IPv4 地址或者是使用16 bytes来存储IPv6地址。存储状态始终在32位平台上占用64个字节,并在64位平台上占用128个字节。考虑到现在的服务器绝大多数都是64位的操作系统,1M的大小可以保留大约8192个128字节的状态。

        当存储空间耗尽的时候,如果需要记录新的值,那么就会通过LRU算法移除旧的变量来腾出空间,如果这样腾出来的空间还是不足以接纳新的记录值,那么nginx就会返回状态码503 (Service Temporarily Unavailable)。此外,为了防止内存耗尽,nginx每次创建一个新记录值的时候就会清理掉两个60秒内没被使用过的旧记录值。

rate: 设定允许的最大请求速率。nginx实现的是毫秒级别的控制粒度,10r/s对应的就是1r/100ms,这也就意味着在没有设置bursts的情况下,如果一个请求接受处理之后的100ms内出现第二个请求,那么它就会被拒绝处理。

   limit_req_zone指令设置了速率限制和共享内存区域的参数,但它实际上并不限制请求速率。因此我们需要通过在contexts中使用limit_req指令来将其限制应用于特定locationserver块。在上面的例子里,我们将请求速率限制在/login/这个location块中。因此现在每个唯一的 IP 地址被限制为每秒 10 个**/login/**请求,或者更准确地说,不能在前一个 URL 请求的 100 毫秒内发出对该 URL 的第二次请求

实例:

limit_req_zone $binary_remote_addr zone=cehis:10m rate=3r/s;server {location /login/ {limit_req zone=ceshi;proxy_pass http://my_upstream;}
}

说明: 使用了limit_req_zone指令定义了一个限速zone,名为ceshi,大小为10m,对应的变量是$binary_remote_addr,限制的请求速率是每秒限制3个请求(3requests/secends),在login这个location中使用limit_req指定了限制的zone

3. limit_req 指令

Syntax: limit_req zone=name [burst=number] [nodelay];
Context: http,server,location

功能: 设置使用哪个共享内存限制域和允许被处理的最大请求数阀值。如果请求的频率超过了限制域配置的值,请求处理会被延迟,所以所有的请求都是以定义的频率被处理的。超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阀值,这时,这个请求会被终止,并返回503(Service Tempporarily Unavailable)错误,这个阀值的默认值为0

说明:

 burst:  可选项。后面接整数,表示最大允许超过频率限制的请求数(这个配置的意思是设置一个大小为number的缓冲区,当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,但是这个等待区里的位置只有number个,超过的请求会直接报503的错误然后返回。)
nodelay: 可选项。如果不希望超过的请求被延迟,可以使用 nodelay 参数(如果设置,会在瞬时提供处理(burst + rate)个请求的能力,请求超过(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况;如果没有设置,则所有请求会依次等待排队)

例子:

limit_req_zone $binary_remote_addr zone=ceshi:10m rate=10r/m; 
limit_req zone=ceshi;
#不加burst和不加nodelay

说明:定义的名为ceshi的limit_req_zone(其定义的限制频率为每分钟的请求数为10个,即每6秒1次),假设同一客户端在同一时刻发起50个请求(前提这50个请求在服务器在6秒内收到),那么,服务器只会成功响应一次请求,对于其余49次请求服务器均不予响应并直接返回了503。

limit_req zone=ceshi burst=5;
#只加burst和不加nodelay

说明: 定义的名为ceshi的limit_req_zone(其定义的限制频率为每分钟的请求数为10个,即每6秒1次),假设同一客户端在同一时刻发起50个请求,那么,服务器只会成功响应5+1=6次请求,但是这6次成功的请求会延时限制(其中第一次成功被服务器处理的请求是在6秒内,第二次是在大于6秒小于12秒内请求成功的,第三次则为大于十二秒小于十八秒内请求成功的,以此类推),对于其余44次请求服务器均不予响应并直接返回了503(这是因为设置了burst=5,在服务器接收到50个并发请求后,先处理1个请求,同时将5个请求放入burst缓冲队列中,等待处理。而超过(burst+1)数量的请求就被直接抛弃了,即直接抛弃了44个请求)

limit_req zone=ceshi burst=5 nodelay;

说明: 定义的名为ceshi的limit_req_zone(其定义的限制频率为每分钟的请求数为10个,即每6秒1次),假设同一客户端在同一时刻发起50个请求(前提这50个请求在服务器在30秒内收到),那么,服务器只会成功响应5+1=6次请求,但是没有时间的限制(即只要服务器处理速度够快,可以在1秒内处理完这6个请求),对于剩下的44个请求,直接返回503,在下一秒如果继续向服务端发送10个请求,服务端会直接拒绝这10个请求并返回503。因为设定了每6s处理1个请求,所以直到30s之后,才可以再处理一个请求,即如果此时向服务端发送10个请求,会返回9个503,一个200

示例

limit_req_zone $binary_remote_addr zone=ceshi:10m rate=5r/s;server {listen 80;location / {limit_req zone=ceshi burst=12 delay=8;proxy_pass http://upstream;}
}

说明: 这个示例是通过limit_req指令和delay参数来实现两段限速,delay参数将nginx配置为允许突发请求以适应典型的web浏览器请求模式,然后将额外的过度请求限制到一定程度,超过该点的额外过度请求将会被拒绝.

        zone为ceshi的大小为10m,5r/s的限制速率一般来说网站通常每个页面有4到6个资源,并且永远不会超过12个资源,该配置允许最多12个请求的突发,其中前8个请求会被转发给upstream处理,在达到5r/s的请求限制之后,从第6个到13个请求会被添加到延迟(delay)中,在之后的任何请求都会被拒绝.


http://www.ppmy.cn/news/1048398.html

相关文章

qt中窗口的布局

qt中窗口的布局 常用的窗口布局方式使用拖拽控件的方式调用窗口布局使用Widget控件完成窗口布局布局中嵌套布局demo(制作登录页面) 如果不使用窗口布局,会带来的后果: 控件可能显示不出来不能按照期望的大小显示不能跟随窗口进行…

CloudQuery实战 | 谁说没有一款一体化数据库操作管控云平台了?

文章目录 CloudQuery询盾的地址CloudQuery主页统一入口数据库归纳SQL编辑器权限管控审计中心数据保护数据变更 CloudQuery文档中心了解CloudQuery快速入门安装步骤社区版v2.1.0操作手册1数据查询更新日志 CloudQuery社区和活动 CloudQuery线上实战线上实战主页面展示及数据操作…

AI夏令营笔记——任务1

任务1 文章目录 任务1任务说明实现思路优化方向conclusion 任务说明 任务要求主要如下: 从论文标题、摘要作者等信息,判断该论文是否属于医学领域的文献。 可以将任务看作是一个文本二分类任务。机器需要根据对论文摘要等信息的理解,将论文…

【SA8295P 源码分析】71 - QAM8295P 原理图参考设计 之 MIPI DSI 接口硬件原理分析

【SA8295P 源码分析】71 - QAM8295P 原理图参考设计 之 MIPI DSI 接口硬件原理分析 一、MIPI-DSI 接口介绍二、高通参考硬件原理图分析:ANX7625 桥接芯片方案2.1 高通参考设计:两路 4-Lane DSI 接口2.2 高通参考设计:DSI0 硬件原理图,将 4 Lane DSI数据通过 ANX7625 桥接芯…

数字化转型时代—人人必学的7项商业分析思维

月説小飞象交流会 人生总有不期而遇的温暖和生生不息的希望。 内部交流│29期 数字化转型时代 人人必学的7项商业分析思维 data analysis ●●●● 分享人:Sophia 数字化时代,数据连接一切,数据驱动一切、数据重塑一切,数据是企业…

el-table根据容器大小自适应滚动条-修改滚动条样式

需求:父容器里有多个容器为上下级,之后浏览器在缩放的时候,上面容器高度改变了,所以el-table被挤压,如果el-table设置的是固定的高度,那么挤压后内容超出父容器,本文章就是解决这个问题 不自适…

UNet深度学习模型在医学图像分割中的应用及其Python实现细节

第一部分:引言和UNet架构简介 引言: 医学图像分割是医疗图像处理的重要领域,它涉及将图像划分为多个区域,以标识和隔离感兴趣的区域(如器官、肿瘤等)。近年来,随着深度学习技术的发展&#xf…

C++入门知识点——解决C语言不足

😶‍🌫️Take your time ! 😶‍🌫️ 💥个人主页:🔥🔥🔥大魔王🔥🔥🔥 💥代码仓库:🔥🔥魔…