limit-req
limit-req 插件使用漏桶算法来限制请求数量并允许进行流量整形。
示例
以下示例演示了如何在不同场景下配置 limit-req。
基于远程地址进行速率限制
以下示例演示了如何通过单个变量 remote_addr 对 HTTP 请求进行速率限制。
创建一个启用了 limit-req 插件的路由,配置为每个远程地址允许 1 QPS:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '
{
"id": "limit-req-route",
"uri": "/get",
"plugins": {
"limit-req": {
"rate": 1,
"burst": 0,
"key": "remote_addr",
"key_type": "var",
"rejected_code": 429,
"nodelay": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ rate:将 QPS 限制为 1。
❷ key:设置为 remote_addr,以根据远程地址应用速率限制配额。
❸ key_type:设置为 var,以将 key 解释为变量。
发送请求进行验证:
curl -i "http://127.0.0.1:9080/get"
你应该会看到一个 HTTP/1.1 200 OK 响应。
该请求已消耗了时间窗口内允许的所有配额。如果你在同一秒内再次发送请求,应该会收到一个 HTTP/1.1 429 Too Many Requests 响应,表明请求超过了配额阈值。
实现 API 流量整形
以下示例演示了如何配置 burst 以允许超过速率限制阈值的请求按配置值进行排队,从而实现请求流量整形。你还将看到与未实施流量整形时的比较。
创建一个启用了 limit-req 插件的路由,配置为每个远程地址允许 1 QPS,burst 为 1:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-req-route",
"uri": "/get",
"plugins": {
"limit-req": {
"rate": 1,
"burst": 1,
"key": "remote_addr",
"rejected_code": 429
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ burst:允许 1 个超过 rate 的请求延迟处理。
生成三个请求到该路由:
resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/get" -o /dev/null -s -w "%{http_code}\n") && \
count_200=$(echo "$resp" | grep "200" | wc -l) && \
count_429=$(echo "$resp" | grep "429" | wc -l) && \
echo "200 responses: $count_200 ; 429 responses: $count_429"
你可能会看到所有三个请求都成功:
200 responses: 3 ; 429 responses: 0
要查看没有 burst 的效果,请将 burst 更新为 0 或将 nodelay 设置为 true,如下所示:
curl "http://127.0.0.1:9180/apisix/admin/routes/limit-req-route" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"plugins": {
"limit-req": {
"nodelay": true
}
}
}'
再次生成三个请求到该路由:
resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/get" -o /dev/null -s -w "%{http_code}\n") && \
count_200=$(echo "$resp" | grep "200" | wc -l) && \
count_429=$(echo "$resp" | grep "429" | wc -l) && \
echo "200 responses: $count_200 ; 429 responses: $count_429"
你应该会看到类似于以下的响应,表明超过速率的请求已被拒绝:
200 responses: 1 ; 429 responses: 2
基于远程地址和消费者名称进行速率限制
以下示例演示了如何通过变量组合 remote_addr 和 consumer_name 对请求进行速率限制。
创建一个启用了 limit-req 插件的路由,配置为允许每个远程地址和每个消费者 1 QPS。
创建一个消费者 john:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "john"
}'
为该消费者创建 key-auth 凭证:
curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-john-key-auth",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'
创建第二个消费者 jane:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "jane"
}'
为该消费者创建 key-auth 凭证:
curl "http://127.0.0.1:9180/apisix/admin/consumers/jane/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"key-auth": {
"key": "jane-key"
}
}
}'
创建一个启用了 key-auth 和 limit-req 插件的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-req-route",
"uri": "/get",
"plugins": {
"key-auth": {},
"limit-req": {
"rate": 1,
"burst": 0,
"key": "$remote_addr $consumer_name",
"key_type": "var_combination",
"rejected_code": 429
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ key-auth:在路由上启用密钥认证。
❷ key:设置为 $remote_addr $consumer_name,以根据远程地址和消费者应用速率限制配额。
❸ key_type:设置为 var_combination,以将 key 解释为变量组合。
同时发送两个请求,每个消费者一个:
curl -i "http://127.0.0.1:9080/get" -H 'apikey: jane-key' & \
curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key' &
你应该收到两个请求的 HTTP/1.1 200 OK 响应,表明每个消费者的请求均未超过阈值。
如果你在同一秒内作为任一消费者发送更多请求,你应该会收到一个 HTTP/1.1 429 Too Many Requests 响应。
这验证了插件是根据变量组合 remote_addr 和 consumer_name 进行速率限制的。