使用 Nginx `limit_req_zone` 限制 IP 访问速率:实战测试与解析

426 阅读3分钟

在 Web 服务中,为了防止恶意攻击或过度使用资源,限制每个 IP 的访问速率是非常必要的。Nginx 提供了一个强大的模块 limit_req_zone,可以用来限制每个 IP 的请求速率。本文将详细介绍如何使用 limit_req_zone 来限制 IP 访问速率为每秒 2 次(2r/s),并通过实际测试展示其效果。

配置步骤

  1. 定义限流区域

    首先,我们需要在 Nginx 配置文件中定义一个限流区域。这个区域会根据 IP 地址($binary_remote_addr)来限制请求速率。以下是一个示例配置:

    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 次。
  2. 应用限流规则

    接下来,我们需要在具体的 server 块或 location 块中应用这个限流规则。以下是一个示例:

    server {
        listen 80;
        server_name example.com;
    
        location / {
            limit_req zone=mylimit;
            # 其他配置,如代理传递、静态文件服务等
        }
    }
    

    在这个配置中,所有对 / 路径的请求都将受到限流规则的限制。

实际测试

为了验证限流规则的效果,我们可以进行以下测试:

  1. 正常访问测试

    使用一个客户端(如浏览器或 curl 命令)以正常速率(每秒不超过 2 次)访问服务器。以下是一个使用 curl 的示例:

    for i in {1..10}; do
        curl -o /dev/null -s -w "%{time_total}\n" http://example.com/
        sleep 0.6  # 稍作延迟,确保每秒不超过2次请求
    done
    

    运行结果可能显示每次请求的处理时间都在合理范围内,没有请求被拒绝。

  2. 并发访问测试

    使用一个脚本或工具(如 Apache Bench 或自定义的并发请求脚本)在非常短的时间内并发发送多个请求。以下是一个使用 Apache Bench 的示例:

    ab -n 10 -c 5 http://example.com/
    
    • -n 10:表示总共发送 10 个请求。
    • -c 5:表示同时并发 5 个请求。

    运行结果

    • 部分请求可能会成功,但超过限流速率(2r/s)的请求将被 Nginx 拒绝,返回状态码可能是 429 Too Many Requests

    • 在 Apache Bench 的输出结果中,可能会看到类似以下的错误提示:

      Failed requests:        3
      (Connect: 0, Length: 0, Exceptions: 3)
      

      这表示有 3 个请求因为限流规则而失败。

结论

通过以上的配置和测试,我们可以得出以下结论:

  • Nginx 的 limit_req_zone 模块可以有效地限制每个 IP 的访问速率,防止恶意攻击或过度使用资源。
  • 当单个 IP 在非常短的时间内并发发送多个请求时,超过限流速率的请求将被拒绝,返回 429 Too Many Requests 状态码。
  • 通过实际测试,我们可以验证限流规则的效果,并根据需要调整限流速率和内存分配。

希望本文对你有所帮助,如果你有任何问题或建议,请随时留言交流。