配置限流
限流允许你限制客户端在特定时间窗口内可以向 API 发起的请求数量。它可以防止后端服务因请求过多而被压垮,并确保 所有用户公平使用服务。
API7 企业版提供两个用于限流的插件:
limit-count:简单限流插件,用于统计固定时间窗口内的请求数。limit-count-advanced:高级版本,支持滑动窗口、多规则和 Redis Sentinel。
前提条件
- API7 企业版实例正在运行。
- 已创建网关组,并且网关实例正在运行。
- Dashboard Token。
配置基础限流
limit-count插件适合简单限流场景,例如限制每个 IP 地址每分钟最多 5 个请求。
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/services/rate-limit-service?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "rate-limit-service",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{
"host": "httpbin.org",
"port": 80,
"weight": 100
}
]
}
}'
curl -k "https://localhost:7443/apisix/admin/routes/rate-limit-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "rate-limit-route",
"methods": ["GET"],
"paths": ["/get"],
"service_id": "rate-limit-service",
"plugins": {
"limit-count": {
"count": 5,
"time_window": 60,
"rejected_code": 429,
"rejected_msg": "Too Many Requests",
"key": "remote_addr",
"policy": "local"
}
}
}'
adc.yaml
services:
- name: rate-limit-service
upstream:
nodes:
- host: httpbin.org
port: 80
weight: 1
routes:
- name: rate-limit-route
uris:
- /get
plugins:
limit-count:
count: 5
time_window: 60
rejected_code: 429
rejected_msg: "Too Many Requests"
key_type: var
key: remote_addr
policy: local
adc sync -f adc.yaml
配置分布式限流
在多节点网关部署中,使用 redis 策略可以在所有节点之间共享限流计数器。
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/services/distributed-rate-limit-service?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "distributed-rate-limit-service",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{
"host": "httpbin.org",
"port": 80,
"weight": 100
}
]
}
}'
curl -k "https://localhost:7443/apisix/admin/routes/distributed-rate-limit-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "distributed-rate-limit-route",
"methods": ["GET"],
"paths": ["/get"],
"service_id": "distributed-rate-limit-service",
"plugins": {
"limit-count": {
"count": 100,
"time_window": 60,
"policy": "redis",
"redis_host": "127.0.0.1",
"redis_port": 6379,
"redis_password": "your-password",
"redis_database": 0,
"allow_degradation": true
}
}
}'
adc.yaml
services:
- name: distributed-rate-limit-service
upstream:
nodes:
- host: httpbin.org
port: 80
weight: 1
routes:
- name: distributed-rate-limit-route
uris:
- /get
plugins:
limit-count:
count: 100
time_window: 60
policy: redis
redis_host: "127.0.0.1"
redis_port: 6379
redis_password: "your-password"
redis_database: 0
allow_degradation: true
adc sync -f adc.yaml
将 allow_degradation 设置为 true 后,即使 Redis 服务器不可达,也会允许流量通过。
配置高级限流
limit-count-advanced插件支持滑动窗口算法,可以避免固定窗口边界处可能出现的流量突增。它还允许在单个插件实例中定义多条规则。
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/services/advanced-rate-limit-service?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "advanced-rate-limit-service",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{
"host": "httpbin.org",
"port": 80,
"weight": 100
}
]
}
}'
curl -k "https://localhost:7443/apisix/admin/routes/advanced-rate-limit-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "advanced-rate-limit-route",
"methods": ["GET"],
"paths": ["/get"],
"service_id": "advanced-rate-limit-service",
"plugins": {
"limit-count-advanced": {
"window_type": "sliding",
"rules": [
{
"count": 10,
"time_window": 1,
"key": "remote_addr"
},
{
"count": 1000,
"time_window": 3600,
"key": "remote_addr"
}
]
}
}
}'
adc.yaml
services:
- name: advanced-rate-limit-service
upstream:
nodes:
- host: httpbin.org
port: 80
weight: 1
routes:
- name: advanced-rate-limit-route
uris:
- /get
plugins:
limit-count-advanced:
window_type: sliding
rules:
- count: 10
time_window: 1
key: remote_addr
- count: 1000
time_window: 3600
key: remote_addr
adc sync -f adc.yaml
在此示例中,一个客户端会同时受到每秒 10 个请求以及每小时 1,000 个请求的限制。
验证配置
向已配置的路由发送多个请求以触发限流:
for i in {1..6}; do curl -I "http://127.0.0.1:9080/get"; done
达到限制时,你将收到 429 Too Many Requests(或自定义 rejected_code)响应。
如果应用配置后路由立即返回 404,请等待几秒钟,让最新配置下发到网关后再重试。
如果启用了 show_limit_quota_header(默认为 true),响应还会包含 X-RateLimit 相关响应头:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 45
故障排除
- Redis 连接问题:确保网关节点能够通过网络访问 Redis 服务器,并且凭证正确。检查网关日志中是否存在连接错误。
- 错误的
key_type:如果你在key中使用变量,请确保key_type设置为var。如果使用常量字符串,请将其设置为constant。 - Redis 延迟:如果 Redis 延迟影响请求性能,可考虑对高频低延迟限制使用
local策略,或调优基于 Redis 策略的sync_interval。