限流限速 #

概述 #

限流限速是保护服务免受滥用和过载的重要手段,Caddy 提供了多种限流机制,包括请求频率限制、连接限制等。

text
┌─────────────────────────────────────────────────────────────┐
│                    限流限速层次                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│    1. 连接层 - 限制并发连接数                                │
│         ↓                                                   │
│    2. 请求层 - 限制请求频率                                  │
│         ↓                                                   │
│    3. 响应层 - 限制响应带宽                                  │
│         ↓                                                   │
│    4. 应用层 - 后端服务保护                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

请求频率限制 #

基本配置 #

caddyfile
example.com {
    rate_limit {
        zone general {
            key {remote_host}
            events 100
            window 1m
        }
    }
    
    reverse_proxy localhost:3000
}

多区域限制 #

caddyfile
example.com {
    rate_limit {
        # 全局限制
        zone global {
            key {remote_host}
            events 1000
            window 1h
        }
        
        # API 限制
        zone api {
            key {remote_host}
            events 100
            window 1m
        }
        
        # 登录限制
        zone login {
            key {remote_host}
            events 5
            window 1m
        }
    }
    
    reverse_proxy localhost:3000
}

路径级限流 #

caddyfile
example.com {
    # API 路径限流
    handle /api/* {
        rate_limit {
            zone api {
                key {remote_host}
                events 100
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 登录路径严格限流
    handle /login {
        rate_limit {
            zone login {
                key {remote_host}
                events 5
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 其他路径宽松限流
    handle {
        rate_limit {
            zone general {
                key {remote_host}
                events 1000
                window 1h
            }
        }
        reverse_proxy localhost:3000
    }
}

限流键类型 #

caddyfile
example.com {
    rate_limit {
        # 按 IP 限流
        zone by_ip {
            key {remote_host}
            events 100
            window 1m
        }
        
        # 按路径限流
        zone by_path {
            key {path}
            events 1000
            window 1m
        }
        
        # 按用户限流(需要认证)
        zone by_user {
            key {http.auth.user.id}
            events 200
            window 1m
        }
        
        # 组合键
        zone combined {
            key {remote_host}{path}
            events 50
            window 1m
        }
    }
}

自定义限流响应 #

caddyfile
example.com {
    rate_limit {
        zone api {
            key {remote_host}
            events 100
            window 1m
        }
    }
    
    # 限流响应
    handle_errors 429 {
        respond `{"error": "Too many requests", "retry_after": "60"}` 429
    }
    
    reverse_proxy localhost:3000
}

连接限制 #

服务器级连接限制 #

caddyfile
{
    servers {
        # 最大空闲连接数
        max_header_size 16KB
        
        # 协议
        protocols h1 h2 h3
    }
}

example.com {
    reverse_proxy localhost:3000
}

代理连接限制 #

caddyfile
example.com {
    reverse_proxy localhost:3000 {
        # 连接池设置
        transport http {
            # 最大空闲连接
            keepalive_idle_conns 100
            
            # 每主机最大空闲连接
            keepalive_idle_conns_per_host 10
            
            # 连接超时
            dial_timeout 5s
        }
    }
}

请求体限制 #

大小限制 #

caddyfile
example.com {
    # 限制请求体大小
    request_body {
        max_size 10MB
    }
    
    reverse_proxy localhost:3000
}

路径级限制 #

caddyfile
example.com {
    # 上传路径允许大文件
    handle /upload/* {
        request_body {
            max_size 100MB
        }
        reverse_proxy localhost:3000
    }
    
    # API 路径限制小文件
    handle /api/* {
        request_body {
            max_size 1MB
        }
        reverse_proxy localhost:3000
    }
}

超时控制 #

请求超时 #

caddyfile
example.com {
    reverse_proxy localhost:3000 {
        transport http {
            # 读取超时
            read_timeout 30s
            
            # 写入超时
            write_timeout 30s
            
            # 拨号超时
            dial_timeout 5s
        }
    }
}

响应超时 #

caddyfile
example.com {
    reverse_proxy localhost:3000 {
        # 响应超时
        transport http {
            response_header_timeout 10s
        }
    }
}

带宽限制 #

响应限速 #

caddyfile
example.com {
    reverse_proxy localhost:3000 {
        # 限制响应带宽(需要插件支持)
        flush_interval 100ms
    }
}

高级限流配置 #

分布式限流 #

caddyfile
{
    # 使用 Redis 存储限流状态(需要插件)
    storage redis {
        host redis.example.com
        port 6379
    }
}

example.com {
    rate_limit {
        zone distributed {
            key {remote_host}
            events 1000
            window 1m
        }
    }
    
    reverse_proxy localhost:3000
}

动态限流 #

bash
# 通过 API 调整限流配置
curl -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "events": 200,
        "window": "1m"
    }' \
    localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0/routes/0/handle/0

白名单 #

caddyfile
example.com {
    # 内网不限流
    @internal remote_ip 10.0.0.0/8 192.168.0.0/16
    
    handle @internal {
        reverse_proxy localhost:3000
    }
    
    # 外网限流
    handle {
        rate_limit {
            zone external {
                key {remote_host}
                events 100
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
}

完整示例 #

API 网关限流 #

caddyfile
api.example.com {
    # 公共 API
    handle /public/* {
        rate_limit {
            zone public {
                key {remote_host}
                events 100
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 私有 API
    handle /private/* {
        rate_limit {
            zone private {
                key {remote_host}
                events 1000
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 认证 API - 严格限流
    handle /auth/* {
        rate_limit {
            zone auth {
                key {remote_host}
                events 10
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 限流错误处理
    handle_errors 429 {
        header Content-Type application/json
        respond `{"error": "Rate limit exceeded", "retry_after": 60}` 429
    }
}

电商网站限流 #

caddyfile
shop.example.com {
    # 静态资源 - 宽松限流
    handle /static/* {
        rate_limit {
            zone static {
                key {remote_host}
                events 5000
                window 1m
            }
        }
        file_server
    }
    
    # 产品浏览
    handle /products/* {
        rate_limit {
            zone browse {
                key {remote_host}
                events 200
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 搜索
    handle /search {
        rate_limit {
            zone search {
                key {remote_host}
                events 30
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 购物车
    handle /cart/* {
        rate_limit {
            zone cart {
                key {remote_host}
                events 100
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 结账 - 严格限流
    handle /checkout/* {
        rate_limit {
            zone checkout {
                key {remote_host}
                events 10
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
    
    # 登录 - 最严格限流
    handle /login {
        rate_limit {
            zone login {
                key {remote_host}
                events 5
                window 1m
            }
        }
        reverse_proxy localhost:3000
    }
}

多租户限流 #

caddyfile
api.example.com {
    # 根据租户 ID 限流
    rate_limit {
        zone tenant {
            key {header.X-Tenant-ID}
            events 1000
            window 1m
        }
    }
    
    reverse_proxy localhost:3000
}

限流最佳实践 #

1. 分层限流 #

caddyfile
# 全局限制 + 路径限制
rate_limit {
    zone global {
        key {remote_host}
        events 1000
        window 1h
    }
}

handle /api/* {
    rate_limit {
        zone api {
            key {remote_host}
            events 100
            window 1m
        }
    }
}

2. 白名单内网 #

caddyfile
@internal remote_ip 10.0.0.0/8
handle @internal {
    # 内网不限流
    reverse_proxy localhost:3000
}

handle {
    rate_limit { ... }
    reverse_proxy localhost:3000
}

3. 友好的错误响应 #

caddyfile
handle_errors 429 {
    header Content-Type application/json
    respond `{
        "error": "Too Many Requests",
        "message": "Please slow down",
        "retry_after": 60
    }` 429
}

4. 监控限流状态 #

bash
# 查看限流统计
curl localhost:2019/metrics | grep rate_limit

故障排查 #

检查限流状态 #

bash
# 查看 API 状态
curl localhost:2019/config/ | jq '.apps.rate_limit'

# 查看日志
tail -f /var/log/caddy/access.log | grep 429

调试限流 #

bash
# 测试限流
for i in {1..200}; do
    curl -s -o /dev/null -w "%{http_code}\n" https://example.com/api/test
done

# 应该看到 200 变为 429

下一步 #

现在你已经掌握了限流限速配置,接下来学习 性能优化 了解如何进一步优化 Caddy 性能!

最后更新:2026-03-28