# ============================================================
# Nginx 请求速率限制配置示例
# ============================================================
#
# 功能说明:
# - 限制请求速率，防止滥用
# - 令牌桶和滑动窗口算法
# - 支持突发流量缓冲
#
# Lolly 对应配置:
# server:
#   security:
#     rate_limit:
#       request_rate: 100  # 每秒请求数
#       burst: 50          # 突发上限
#       conn_limit: 100    # 连接数限制
#       key: "ip"          # 限流键（ip 或 header）
#       algorithm: "token_bucket"  # 或 "sliding_window"
#       sliding_window: 60         # 窗口大小（秒）
# ============================================================

# 定义限流区域（http 块）
http {
    # 请求速率限制区域
    # rate=10r/s 表示每秒 10 个请求
    # Lolly 对应: request_rate, burst, key
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

    # 基于 Header 的限流（如用户 ID）
    limit_req_zone $http_x_api_key zone=api_limit:10m rate=100r/s;

    # 基于 URI 的限流
    limit_req_zone $binary_remote_addr$uri zone=uri_limit:10m rate=5r/s;

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

        # 基础请求限流
        location /api {
            # burst=5 允许突发 5 个请求
            # nodelay: 突发请求立即处理（不排队）
            # Lolly 对应: request_rate: 10, burst: 5
            limit_req zone=req_limit burst=5 nodelay;

            # 限流时返回的状态码
            limit_req_status 429;

            proxy_pass http://backend:8080;
        }

        # API Key 限流
        location /api/v2 {
            limit_req zone=api_limit burst=20 nodelay;
            limit_req_status 429;

            proxy_pass http://backend:8080;
        }

        # 登录接口严格限流
        location /login {
            # 禁止突发，严格限制
            limit_req zone=req_limit burst=1;
            limit_req_status 429;

            # 自定义限流响应
            limit_req_log_level warn;

            proxy_pass http://backend:8080;
        }

        # 限流白名单
        # 使用 map 变量实现
        set $limit_key $binary_remote_addr;
        if ($remote_addr = "10.0.0.1") {
            set $limit_key "";
        }

        location /internal {
            # $limit_key 为空时不受限制
            limit_req zone=req_limit burst=100;

            proxy_pass http://backend:8080;
        }

        # 限流错误页面
        error_page 429 = @rate_limit_error;
        location @rate_limit_error {
            default_type application/json;
            return 429 '{"error": "Rate limit exceeded", "retry_after": 60}';
        }
    }
}

# 速率限制说明:
#
# 1. 令牌桶算法:
#    - rate: 每秒生成令牌数
#    - burst: 桶容量（允许突发）
#    - nodelay: 突发立即处理
#    - Lolly 对应: algorithm: "token_bucket"
#
# 2. 滑动窗口算法:
#    - 精确计算窗口内请求数
#    - Lolly 对应: algorithm: "sliding_window"
#    - sliding_window: 窗口大小（秒）
#
# 3. 限流键:
#    - $binary_remote_addr: IP 地址（二进制，节省内存）
#    - $http_header: 自定义 Header
#    - Lolly 对应: key: "ip" 或 key: "header"
#
# 4. 内存分配:
#    - zone=name:size 定义共享内存区域
#    - 10m 可存储约 16 万 IP 状态
#
# 5. 状态码:
#    - limit_req_status: 限流时返回的状态码
#    - 建议 429 (Too Many Requests)