插件窝 干货文章 Nginx怎么配置抢购限流

Nginx怎么配置抢购限流

limit zone server req 483    来源:    2025-04-24

Nginx配置抢购限流方案

在高并发抢购场景下,合理的限流配置可以保护后端服务不被压垮。以下是几种Nginx限流配置方案:

1. 基于连接数限流

限制单个IP的连接数

http {
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_status 429; # 返回429状态码

    server {
        location /seckill {
            limit_conn perip 10; # 每个IP最多10个并发连接
            proxy_pass http://backend;
        }
    }
}

2. 基于请求速率限流

限制请求速率

http {
    limit_req_zone $binary_remote_addr zone=req_perip:10m rate=5r/s;

    server {
        location /seckill {
            limit_req zone=req_perip burst=10 nodelay;
            proxy_pass http://backend;
        }
    }
}
  • rate=5r/s:每秒5个请求
  • burst=10:允许突发10个请求
  • nodelay:不延迟处理突发请求

3. 基于漏桶算法的限流

http {
    limit_req_zone $binary_remote_addr zone=leaky:10m rate=10r/s;

    server {
        location /seckill {
            limit_req zone=leaky burst=20;
            proxy_pass http://backend;
        }
    }
}

4. 结合Lua脚本实现更灵活的限流

http {
    lua_shared_dict limit_locks 100k;

    server {
        location /seckill {
            access_by_lua_block {
                local locks = ngx.shared.limit_locks
                local key = "seckill:" .. ngx.var.remote_addr
                local limit = 5 -- 每秒5次

                local current = locks:get(key) or 0
                if current >= limit then
                    ngx.exit(429)
                else
                    locks:incr(key, 1, 0)
                    locks:expire(key, 1) -- 1秒后过期
                end
            }
            proxy_pass http://backend;
        }
    }
}

5. 商品级别的限流

http {
    map $arg_item_id $limit_key {
        default $binary_remote_addr;
        "123" "item_123"; # 对特定商品单独限流
    }

    limit_req_zone $limit_key zone=item_limits:10m rate=100r/s;

    server {
        location /seckill {
            limit_req zone=item_limits burst=50;
            proxy_pass http://backend;
        }
    }
}

最佳实践建议

  1. 分层限流:结合Nginx限流和应用层限流
  2. 白名单机制:为内部系统或VIP用户设置白名单
  3. 动态调整:根据系统负载动态调整限流阈值
  4. 优雅降级:限流时返回友好提示或排队页面
  5. 监控报警:实时监控限流触发情况

完整示例配置

http {
    # 定义限流区域
    limit_conn_zone $binary_remote_addr zone=conn_perip:10m;
    limit_req_zone $binary_remote_addr zone=req_perip:10m rate=10r/s;
    limit_req_zone $server_name zone=req_perserver:10m rate=1000r/s;

    # 白名单设置
    geo $limit {
        default 1;
        10.0.0.0/8 0; # 内网IP不限流
        192.168.0.0/16 0;
    }

    map $limit $limit_key {
        0 "";
        1 $binary_remote_addr;
    }

    server {
        listen 80;
        server_name seckill.example.com;

        # 全局限流
        limit_req zone=req_perserver burst=2000;

        location /seckill {
            # IP级别限流
            limit_req zone=req_perip burst=20 nodelay;
            limit_conn conn_perip 5;

            # 连接超时设置
            proxy_connect_timeout 3s;
            proxy_read_timeout 5s;
            proxy_send_timeout 5s;

            # 其他配置
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://backend_servers;
        }

        error_page 429 /429.html;
        location = /429.html {
            root /usr/share/nginx/html;
            internal;
        }
    }

    upstream backend_servers {
        server 10.0.0.1:8080;
        server 10.0.0.2:8080;
        keepalive 32;
    }
}

以上配置可以根据实际业务需求进行调整,建议在测试环境充分验证后再上线使用。