nginx限流

这篇博客探讨了NGINX的limit_req模块,特别是burst和nodelay参数如何影响速率限制策略。burst参数定义了超过限制时可排队的请求数量,而nodelay选项改变了请求处理的方式,允许立即转发请求而不等待间隔。通过示例,解释了这两个参数如何协同工作以实现更灵活的速率限制,以及如何影响超出限制时的请求处理。
location /login/ {
    limit_req zone=mylimit burst=20 nodelay;
 
    proxy_pass http://my_upstream;
}

burst参数定义了客户端可以发出多少请求超过区域指定的速率(对于我们的示例mylimit区域,速率限制为每秒 10 个请求,或每 100 毫秒 1 个请求)。一个在前一个请求后 100 毫秒内到达的请求被放入队列,这里我们将队列大小设置为 20。

这意味着如果 21 个请求同时从给定 IP 地址到达,NGINX 会立即将第一个请求转发到上游服务器组,并将剩余的 20 个放入队列中。然后它每 100 毫秒转发一个排队的请求,并且503仅当传入请求使排队的请求数超过 20 时才返回客户端

使用该nodelay参数,NGINX 仍然根据参数分配队列中的槽burst并施加配置的速率限制,但不是通过间隔排队请求的转发。相反,当请求“过早”到达时,只要队列中有可用的插槽,NGINX 就会立即转发它。它将该槽标记为“已占用”,并且在经过适当的时间(在我们的示例中为 100 毫秒之后)之前,不会将其释放以供另一个请求使用。

和前面一样,假设 20 个插槽的队列是空的,并且来自给定 IP 地址的 21 个请求同时到达。NGINX 立即转发所有 21 个请求并将队列中的 20 个插槽标记为已占用,然后每 100 毫秒释放 1 个插槽。(如果有 25 个请求,NGINX 将立即转发其中的 21 个,将 20 个插槽标记为已占用,并拒绝 4 个状态为 的请求 503。)

现在假设在第一组请求被转发后的 101 毫秒,另外 20 个请求同时到达。队列中只有 1 个插槽已被释放,因此 NGINX 转发 1 个请求并以 status 拒绝其他 19 个请求 503。如果在 20 个新请求到达之前已经过去了 501 毫秒,则 5 个插槽是空闲的,因此 NGINX 立即转发 5 个请求并拒绝 15 个。

效果相当于每秒 10 个请求的速率限制。如果您想在不限制请求之间允许的间距的情况下施加速率限制,该nodelay选项很有用。

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;
            # ...
        }
    }
}

limit_req您可以在一个位置包含多个指令。应用与给定请求匹配的所有限制,这意味着使用最严格的限制。例如,如果多个指令强加了延迟,则使用最长的延迟。同样,如果这是任何指令的效果,请求也会被拒绝,即使其他指令允许它们通过。

location /login/ {
    limit_req zone=mylimit burst=20 nodelay;
    limit_req_status 444;   // 默认503
}
### Nginx限流配置教程 Nginx 提供了一个模块 `ngx_http_limit_req_module` 来实现请求速率限制的功能。此模块的核心在于定义一个共享内存区用来存储会话状态,并通过指定的键(如 IP 地址)来跟踪请求频率。 #### 配置步骤说明 1. **创建共享内存区域** 使用 `limit_req_zone` 指令可以定义一个共享内存区域,用于保存访问者的状态信息。例如,基于客户端 IP 地址进行限流时,可按如下方式设置: ```nginx http { limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s; } ``` 这里 `$binary_remote_addr` 是指客户端的二进制形式 IP 地址,`zone=mylimit:10m` 定义名为 `mylimit` 的共享内存区域大小为 10MB,而 `rate=2r/s` 则表示每秒允许的最大请求数为 2次[^1]。 2. **应用流限制到具体位置** 单独定义 `limit_req_zone` 并不会实际生效,还需要配合 `limit_req` 指令将其作用于具体的 location 或 server 块中。下面是一个针对 `/login/` 路径实施限流的例子: ```nginx server { listen 80; location /login/ { limit_req zone=mylimit burst=5 nodelay; proxy_pass http://backend_server; } } ``` 上述配置中的 `burst=5` 参数意味着当超过设定速率时,额外最多允许排队等待处理的请求数为 5;`nodelay` 取消延迟机制,使得超出部分立即被处理而不是逐步释放队列中的请求[^2]。 3. **验证效果并调整优化** 配置完成后,可通过分析日志文件确认限流策略是否正常工作。默认情况下,Nginx 日志路径可能位于 `/var/log/nginx/access.log` 和 `/var/log/nginx/error.log` 中。如果希望更直观地观察性能指标变化,则推荐集成 Prometheus 和 Grafana 等监控平台来进行可视化展示[^3]。 4. **深入理解原理** 尽管表面上看设置了固定的速率比如 `rate=2r/s` ,实际上内部是以毫秒级精度控制请求间隔时间。对于本例而言,“2 请求/秒”的含义转换成了“每隔至少 500ms 才能接受下一个新请求”。一旦违反这个规则即触发限流响应[^4]。 ```python # 示例 Python脚本模拟压力测试场景下的表现评估(仅作参考用途) import time, requests url = 'http://example.com/login/' for i in range(10): try: resp = requests.get(url) print(f'Request {i}: Status Code={resp.status_code}') except Exception as e: print(e) finally: time.sleep(.1) # 控制发送速度接近理论阈值附近便于观测行为差异 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值