插件窝 干货文章 在nginx中如何实现单位时间内限制访问频率

在nginx中如何实现单位时间内限制访问频率

限制 limit zone 请求 602    来源:    2025-04-25

Nginx 实现访问频率限制方案

在 Nginx 中,可以通过 limit_req_zonelimit_req 指令来实现单位时间内的访问频率限制。以下是详细实现方法:

基本配置方法

1. 在 http 块中定义限制区域

http {
    # 定义限制区域,名为one,10MB内存空间,限制每秒1个请求
    # $binary_remote_addr 表示以客户端IP作为限制依据
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    # 如果需要限制某个特定变量(如用户ID)
    # limit_req_zone $user_id zone=two:10m rate=10r/m;
}

2. 在 server 或 location 块中应用限制

server {
    location /api/ {
        # 应用名为one的限制区域
        limit_req zone=one;

        # 其他配置...
        proxy_pass http://backend;
    }
}

高级配置选项

1. 允许突发请求

location /api/ {
    # 允许突发5个请求,之后按1r/s限制
    limit_req zone=one burst=5;
}

2. 无延迟处理突发请求

location /api/ {
    # 允许突发5个请求且无延迟
    limit_req zone=one burst=5 nodelay;
}

3. 设置延迟处理

location /api/ {
    # 允许突发5个请求,超过后延迟处理
    limit_req zone=one burst=5 delay=3;
}

4. 设置状态码

location /api/ {
    limit_req zone=one burst=5 nodelay;
    limit_req_status 429; # 默认是503
}

完整示例

http {
    # 限制每个IP每秒10个请求
    limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

    # 限制整个服务每分钟1000个请求
    limit_req_zone $server_name zone=perserver:10m rate=1000r/m;

    server {
        listen 80;
        server_name example.com;

        # 静态文件不限制
        location /static/ {
            alias /var/www/static/;
        }

        # API接口严格限制
        location /api/ {
            limit_req zone=perip burst=20 nodelay;
            limit_req zone=perserver burst=100;
            limit_req_status 429;

            proxy_pass http://api_backend;
        }

        # 登录接口更严格限制
        location /api/login {
            limit_req zone=perip burst=5;
            limit_req_status 429;

            proxy_pass http://api_backend;
        }
    }
}

注意事项

  1. rate 参数可以设置为:

    • r/s (每秒请求数)
    • r/m (每分钟请求数)
  2. 内存大小计算:1MB可以存储约16000个IP地址的状态

  3. 可以结合 limit_conn_zonelimit_conn 进行并发连接数限制

  4. 对于重要接口,建议设置较低的 burst 值防止暴力攻击

  5. 生产环境建议先设置较宽松的限制,然后根据监控逐步调整

这种频率限制机制可以有效防止CC攻击、暴力破解和API滥用等情况。