Nginx之限流

这篇具有很好参考价值的文章主要介绍了Nginx之限流。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

流量限制(rate-limiting),是 Nginx 中一个非常实用,却经常被错误理解和错误配置的功能。我们可以用来限制用户在给定时间内 HTTP 请求的数量。请求,可以是一个简单网站首页的 GET 请求,也可以是登录表单的 POST 请求。

流量限制可以用作安全目的,比如可以减慢暴力密码破解的速率。通过将传入请求的速率限制为真实用户的典型值,并标识目标URL地址(通过日志),还可以用来抵御 DDOS 攻击。更常见的情况,该功能被用来保护上游应用服务器不被同时太多用户请求所压垮。

本篇文章将会介绍 Nginx 的流量限制 的基础知识和高级配置,”流量限制”在 Nginx Plus 中也适用。

Nginx如何限流

Nginx 的”流量限制”使用漏桶算法(leaky bucket algorithm),该算法在通讯和分组交换计算机网络中广泛使用,用以处理带宽有限时的突发情况。就好比,一个桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水将会溢出;同样,在请求处理方面,水代表来自客户端的请求,水桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列,桶底漏出的水代表离开缓冲区被服务器处理的请求,桶口溢出的水代表被丢弃和不被处理的请求。

配置基本的限流

“流量限制”配置两个主要的指令,limit_req_zonelimit_req,如下所示:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
    location /login/ {
        limit_req zone=mylimit;

        proxy_pass http://my_upstream;
    }
}

limit_req_zone指令定义了流量限制相关的参数,而limit_req指令在出现的上下文中启用流量限制(示例中,对于”/login/”的所有请求)。limit_req_zone指令通常在 HTTP 块中定义,使其可在多个上下文中使用,它需要以下三个参数:

  • Key - 定义应用限制的请求特性。示例中的 Nginx 变量remote_addr,占用更少的空间)
  • Zone - 定义用于存储每个 IP 地址状态以及被限制请求 URL 访问频率的共享内存区域。保存在内存共享区域的信息,意味着可以在 Nginx 的 worker 进程之间共享。定义分为两个部分:通过zone=keyword标识区域的名字,以及冒号后面跟区域大小。16000 个 IP 地址的状态信息,大约需要 1MB,所以示例中区域可以存储 160000 个 IP 地址。
  • Rate - 定义最大请求速率。在示例中,速率不能超过每秒 10 个请求。Nginx 实际上以毫秒的粒度来跟踪请求,所以速率限制相当于每 100 毫秒 1 个请求。因为不允许”突发情况”,这意味着在前一个请求 100 毫秒内到达的请求将被拒绝。

当 Nginx 需要添加新条目时存储空间不足,将会删除旧条目。如果释放的空间仍不够容纳新记录,Nginx 将会返回 503 状态码(Service Temporarily Unavailable)。另外,为了防止内存被耗尽,Nginx 每次创建新条目时,最多删除两条 60 秒内未使用的条目。

limit_req_zone指令设置流量限制和共享内存区域的参数,但实际上并不限制请求速率。所以需要通过添加limit_req指令,将流量限制应用在特定的 location 或者 server 块。在上面示例中,我们对/login/请求进行流量限制。

nginx 限流,技术文章,文档,运维,nginx,服务器,运维

现在每个 IP 地址被限制为每秒只能请求 10 次 /login/,更准确地说,在前一个请求的 100 毫秒内不能请求该 URL。

处理突发

如果我们在 100 毫秒内接收到 2 个请求,怎么办?对于第二个请求,Nginx 将给客户端返回状态码 503。这可能并不是我们想要的结果,因为应用本质上趋向于突发性。相反地,我们希望缓冲任何超额的请求,然后及时地处理它们。我们更新下配置,在limit_req中使用 burst 参数:

location /login/ {
    limit_req zone=mylimit burst=20;
    proxy_pass http://my_upstream;
}

burst 参数定义了超出 zone 指定速率的情况下(示例中的 mylimit 区域,速率限制在每秒 10 个请求,或每 100 毫秒一个请求),客户端还能发起多少请求。上一个请求 100 毫秒内到达的请求将会被放入队列,我们将队列大小设置为 20。

这意味着,如果从一个给定 IP 地址发送 21 个请求,Nginx 会立即将第一个请求发送到上游服务器群,然后将余下 20 个请求放在队列中。然后每 100 毫秒转发一个排队的请求,只有当传入请求使队列中排队的请求数超过 20 时,Nginx 才会向客户端返回 503。

无延迟的排队

配置 burst 参数将会使通讯更流畅,但是可能会不太实用,因为该配置会使站点看起来很慢。在上面的示例中,队列中的第 20 个包需要等待 2 秒才能被转发,此时返回给客户端的响应可能不再有用。要解决这个情况,可以在 burst 参数后添加 nodelay 参数:

location /login/ {
    limit_req zone=mylimit burst=20 nodelay;

    proxy_pass http://my_upstream;
}

使用 nodelay 参数,Nginx 仍将根据 burst 参数分配队列中的位置,并应用已配置的速率限制,而不是清理队列中等待转发的请求。相反地,当一个请求到达“太早”时,只要在队列中能分配位置,Nginx 将立即转发这个请求。将队列中的该位置标记为”taken”(占据),并且不会被释放以供另一个请求使用,直到一段时间后才会被释放(在这个示例中是,100 毫秒后)。

假设如前所述,队列中有 20 个空位,从给定的 IP 地址发出的 21 个请求同时到达。Ngin x会立即转发这个 21 个请求,并且标记队列中占据的 20 个位置,然后每 100 毫秒释放一个位置。如果是25个请求同时到达,Nginx 将会立即转发其中的 21 个请求,标记队列中占据的 20 个位置,并且返回 503 状态码来拒绝剩下的 4 个请求。

现在假设,第一组请求被转发后 101 毫秒,另 20 个请求同时到达。队列中只会有一个位置被释放,所以 Nginx 转发一个请求并返回503状态码来拒绝其他 19 个请求。如果在 20 个新请求到达之前已经过去了 501 毫秒,5 个位置被释放,所以 Nginx 立即转发 5 个请求并拒绝另外 15 个。

效果相当于每秒 10 个请求的“流量限制”。如果希望不限制两个请求间允许间隔的情况下实施“流量限制”,nodelay 参数是很实用的。

注意:对于大部分部署,我们建议使用 burst 和 nodelay 参数来配置limit_req指令。

高级配置示例

通过将基本的“流量限制”与其他 Nginx 功能配合使用,我们可以实现更细粒度的流量限制。

「白名单」

下面这个例子将展示,如何对任何不在白名单内的请求强制执行“流量限制”:

geo $limit {
    default         1;
    10.0.0.0/8         0;
    192.168.0.0/64     0;
}
map $limit $limit_key {
    0 "";
    1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
server {
    location / {
        limit_req zone=req_zone burst=10 nodelay;

        # ...
    }
}

这个例子同时使用了 geo 和 map 指令。geo 块将给在白名单中的 IP 地址对应的 $limit 变量分配一个值 0,给其它不在白名单中的分配一个值 1。然后我们使用一个映射将这些值转为 key,如下:

  • 如果变量的值是,limit_key变量将被赋值为空字符串
  • 如果变量的值是,limit_key变量将被赋值为客户端二进制形式的 IP 地址 两个指令配合使用,白名单内 IP 地址的$limit_key变量被赋值为空字符串,不在白名单内的被赋值为客户端的 IP 地址。当limit_req_zone后的第一个参数是空字符串时,不会应用“流量限制”,所以白名单内的 IP 地址(10.0.0.0/8 和192.168.0.0/24 网段内)不会被限制。其它所有 IP 地址都会被限制到每秒 5 个请求。

limit_req指令将限制应用到 /location块,允许在配置的限制上最多超过 10 个数据包的突发,并且不会延迟转发。

location包含多limit_req指令

我们可以在一个 location 块中配置多个limit_req指令。符合给定请求的所有限制都被应用时,意味着将采用最严格的那个限制。例如,多个指令都制定了延迟,将采用最长的那个延迟。同样,请求受部分指令影响被拒绝,即使其他指令允许通过也无济于事。

扩展前面将“流量限制”应用到白名单内 IP 地址的例子:

http {
    # ...

    limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
    limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s;
    server {
        # ...
        location / {
            limit_req zone=req_zone burst=10 nodelay;
            limit_req zone=req_zone_wl burst=20 nodelay;
            # ...
        }
    }
}

白名单内的 IP 地址不会匹配到第一个“流量限制”,而是会匹配到第二个req_zone_wl,并且被限制到每秒 15 个请求。不在白名单内的 IP 地址两个限制能匹配到,所以应用限制更强的那个:每秒 5 个请求。

配置相关功能

日志记录 默认情况下,Nginx 会在日志中记录由于流量限制而延迟或丢弃的请求,如下所示:

2015/06/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, <br>request: "GET / HTTP/1.0", host: "nginx.com"

日志条目中包含的字段:

  • limiting requests - 表明日志条目记录的是被“流量限制”请求
  • excess - 每毫秒超过对应“流量限制”配置的请求数量
  • zone - 定义实施“流量限制”的区域
  • client - 发起请求的客户端 IP 地址
  • server - 服务器 IP 地址或主机名
  • request - 客户端发起的实际 HTTP 请求
  • host - HTTP 报头中 host 的值

默认情况下,Nginx 以 error 级别来记录被拒绝的请求,如上面示例中的[error]所示(Ngin 以较低级别记录延时请求,一般是 info 级别)。如要更改 Nginx 的日志记录级别,需要使用limit_req_log_level指令。这里,我们将被拒绝请求的日志记录级别设置为 warn:

location /login/ {
    limit_req zone=mylimit burst=20 nodelay;
    limit_req_log_level warn;
    
    proxy_pass http://my_upstream;
}

发送到客户端的错误代码

一般情况下,客户端超过配置的流量限制时,Nginx 响应状态码为 503(Service Temporarily Unavailable)。可以使用limit_req_status指令来设置为其它状态码(例如下面的 444 状态码):

location /login/ {
    limit_req zone=mylimit burst=20 nodelay;
    limit_req_status 444;
}

指定location拒绝所有请求

如果你想拒绝某个指定 URL 地址的所有请求,而不是仅仅对其限速,只需要在 location 块中配置 deny all 指令:

location /foo.php {
    deny all;
}
limit_req_status 444;

}

指定location拒绝所有请求

如果你想拒绝某个指定 URL 地址的所有请求,而不是仅仅对其限速,只需要在 location 块中配置 deny all 指令:


location /foo.php {
    deny all;
}

总结

前文已经涵盖了 Nginx 和 Nginx Plus 提供的“流量限制”的很多功能,包括为 HTTP 请求的不同 loation 设置请求速率,给“流量限制”配置 burst 和 nodelay 参数。还涵盖了针对客户端 IP 地址的白名单和黑名单应用不同“流量限制”的高级配置,阐述了如何去日志记录被拒绝和延时的请求。文章来源地址https://www.toymoban.com/news/detail-770378.html

到了这里,关于Nginx之限流的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【全方位解析】如何写好技术文章

    前言 为何而写 技术成长 :相对于庞大的计算机领域的知识体系,人的记忆还是太有限了,而且随着年龄的增大,记忆同样也会逐渐衰退,正如俗话所说“好记性不如烂笔头”。并且在分享博客的过程中,我们也可以和大神交流,进而发现自己的认知错误,纠正知识体系。最

    2024年02月16日
    浏览(41)
  • MongoDB数据库从入门到精通系列文章之:MongoDB数据库百篇技术文章汇总

    MongoDB数据库系列文章持续更新中: 更多数据库内容请阅读博主数据库专栏,数据库专栏涵盖了Mysql、SQLServer、PostgreSQL、MongoDB、Oracle、Cassandra等数据库 数据库专栏 文章名称 文章链接 数据库安装部署系列之:部署Mongodb5.0.6高可用集群详细步骤 数据库安装部署系列之:部署M

    2024年02月11日
    浏览(43)
  • SAP ABAP技术文章合集_微信公众号:ABAP猿

    序号 文章标题 01 ABAP OOALV-基本显示 02 ABAP OOALV-排序、过滤 03 ABAP OOALV-合计、小计 04 ABAP OOALV-选择模式、触发事件 05 ABAP OOALV-隐藏列、修改列标题、添加图标列、调整列位置 06 ABAP OOALV-固定列、鼠标悬停文本 07 ABAP OOALV-颜色(列、行、单元格) 08 ABAP OOALV-样式(列、行、单元格

    2024年02月03日
    浏览(39)
  • 【ARM Cache 系列文章 8 -- ARM DynamIQ 技术介绍

    请阅读 【ARM Cache 系列文章专栏导读】 2017年3月21日下午,ARM在北京金隅喜来登酒店召开发布会,正式发布了全新的有针对人工智能及机器学习进行优化的DynamIQ技术,ARM 称 DynamIQ将是下一代计算革命的开始,将重新定义计算,可以覆盖覆盖从端到云的安全、通用平台。将被广

    2024年02月13日
    浏览(36)
  • 【ARM Cache 系列文章 9 -- ARM big.LITTLE技术】

    转自 :https://zhuanlan.zhihu.com/p/630981648 如有侵权,请联系删除 为满足在移动设备应用领域中的节能需求,ARM于2011年首次提出了big.LITTLE技术。big.LITTLE技术是一种使用两种不同ARM处理器的处理架构技术,即big处理器和LITTLE处理器,big处理器用于提供高性能,LITTLE处理器用于追求

    2024年02月13日
    浏览(33)
  • 云贝教育 |【技术文章】Oracle 19c 单实例dg+rman+copy方案

    软件名称 版本 vmware v15 操作系统 oracle linux 8.8 数据库 19.3.0.0.0 secureCRT 9 类型 IP 主机名 db_name db_unique_name instance_name ORACLE_SID 主库 192.168.2.115 db1 ORCLCDB ORCLCDB1 ORCLCDB1 ORCLCDB1 备库 192.168.254.38 db2 ORCLCDB ORCLCDB2 ORCLCDB2 ORCLCDB1 说明:以下配置无特殊说明,均在CDB下,用SYS用户操作。 1)

    2024年01月23日
    浏览(34)
  • AI写作技术鉴别攻略:8招轻松识别文章是否为AI所写

    诚然,AI写作技术不断进步,产出海量文章,那么我们该怎样辨别一篇文章是否为AI所写呢?接下来我会就此问题分享几招小技巧,教您轻松鉴别AI文章哦。 1.观察语言风格 审阅AI生成的文本时,请留意其是否能够自然地富有情感和生动形象的描绘场景或人物。同时,也欢迎关

    2024年04月13日
    浏览(25)
  • Spring限流之限流方案分析

    限流对于一个微服务架构系统来说具有非常重要的意义,否则其中的某个微服务将成为整个系统隐藏的雪崩因素,为什么这么说? 举例来讲,某个平台有100多个微服务应用,但是作为底层的某个或某几个应用来说,将会被所有上层应用频繁调用,业务高峰期时,如果底层应用

    2024年02月13日
    浏览(28)
  • OSPF技术连载16:DR和BDR选举机制,一篇文章搞定!

    你好,这里是网络技术联盟站。 在计算机网络中,开放最短路径优先(Open Shortest Path First,OSPF)是一种广泛使用的内部网关协议(Interior Gateway Protocol,IGP),用于在大型网络中实现路由选择。在OSPF网络中,当一个OSPF区域内有多个路由器时,为了减少链路状态数据库(Link

    2024年02月07日
    浏览(33)
  • 【人工智能】谷歌 Bard 写文章能力测评:人类技术革命的历史—— GPT-4 危险了,论技术看来还是Google牛逼啊

    目录 人类技术革命的历史 第一次技术革命:新石器时代革命 第二次技术革命:工业革命

    2024年02月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包