limit-count-advanced
limit-count-advanced 插件使用固定窗口或滑动窗口算法,通过限制给定时间间隔内的请求数量来限制请求速率。超过配置配额的请求将被拒绝。
具体来说:
- 固定窗口算法在不重叠的时间间隔内跟踪请求。如果请求计数在任何间隔内超过配额,多余的请求将立即被拒绝,直到下一个时间窗口开始。
- 滑动窗口算法在重叠的间隔内跟踪请求,通过计算过去配置的时间段内的最近请求来平滑速率限制,而不管间隔何时开始。此方法减少了流量峰值,并且更有效地在一段时间内均匀分布请求。
此外,你可能还会看到以下速率限制响应头,其名称可以使用插件元数据进行自定义:
X-RateLimit-Limit:总配额X-RateLimit-Remaining:剩余配额X-RateLimit-Reset:计数器重置前的剩余秒数
偶尔,你可能会观察到 X-RateLimit-Remaining 出现较小的负值。这是可以接受的,因为滑动窗口算法是一种近似值。
本地限速与基于 Redis 的限速
limit-count-advanced 插件支持两种限速模式:
- 本地限速:每个网关实例独立实施限速。每个实例维护自己的计数器,因此当流量分散到多个实例时,实际限额约为“限额 × 实例数”。未设置
policy或将其设置为local时,这是默认模式。 - 基于 Redis 的限速:通过 Redis 在所有网关实例之间共享限额。所有实例共享同一配额,因此配置的限额适用于全部网关实例。
示例
除了 limit-count 插件功能外,该插件还支持滑动窗口算法。请参考 limit-count 插件以获取固定窗口示例,这些示例也可以在 limit-count-advanced 中配置。
以下示例演示了如何使用 limit-count-advanced 进行滑动窗口算法的速率限制。
使用本地计数器进行速率限制
以下示例演示了如何配置 limit-count-advanced 在路由上使用滑动窗口算法进行速率限制,并使用网关中的计数器。请注意,每个网关实例都有自己的计数器和独立配额。如果你有多个网关实例需要共享相同的配额,请参阅使用 Redis 服务器在网关之间共享配额。
创建一个启用了 limit-count-advanced 插件的路由,配置为每个远程地址在 10 秒滑动窗口内允许的配额为 5:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-sliding-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"policy": "local",
"count": 5,
"time_window": 10,
"rejected_code": 429,
"key_type": "var",
"key": "remote_addr",
"window_type": "sliding"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /get
name: limit-count-sliding-route
plugins:
limit-count-advanced:
policy: local
count: 5
time_window: 10
rejected_code: 429
key_type: var
key: remote_addr
window_type: sliding
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: limit-count-advanced-plugin-config
spec:
plugins:
- name: limit-count-advanced
config:
policy: local
count: 5
time_window: 10
rejected_code: 429
key_type: var
key: remote_addr
window_type: sliding
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: limit-count-sliding-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /get
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-advanced-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: limit-count-sliding-route
spec:
ingressClassName: apisix
http:
- name: limit-count-sliding-route
match:
paths:
- /get
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: limit-count-advanced
config:
policy: local
count: 5
time_window: 10
rejected_code: 429
key_type: var
key: remote_addr
window_type: sliding
应用配置:
kubectl apply -f limit-count-advanced-ic.yaml
每隔一秒生成 7 个请求到该路由:
for i in $(seq 7); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done
你应该收到大多数请求的 HTTP/1.1 200 OK 响应,其余为 HTTP 429 Too Many Requests 响应。具体被拒绝的数量取决于第一个请求发送的时间。
使用 Redis 服务器在网关之间共享配额
以下示例演示了如何使用 Redis 服务器在多个网关节点之间使用滑动窗口算法进行速率限制,从而使不同的网关节点共享相同的速率限制配额。
在网关组中创建一个具有以下配置的路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-sliding-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 1,
"time_window": 30,
"rejected_code": 429,
"key": "remote_addr",
"policy": "redis",
"redis_host": "192.168.xxx.xxx",
"redis_port": 6379,
"redis_password": "p@ssw0rd",
"redis_database": 1,
"window_type": "sliding",
"sync_interval": 0.2
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /get
name: limit-count-sliding-route
plugins:
limit-count-advanced:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis
redis_host: "192.168.xxx.xxx"
redis_port: 6379
redis_password: "p@ssw0rd"
redis_database: 1
window_type: sliding
sync_interval: 0.2
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: limit-count-advanced-plugin-config
spec:
plugins:
- name: limit-count-advanced
config:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis
redis_host: "redis-service.aic.svc"
redis_port: 6379
redis_password: "p@ssw0rd"
redis_database: 1
window_type: sliding
sync_interval: 0.2
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: limit-count-sliding-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /get
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-advanced-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: limit-count-sliding-route
spec:
ingressClassName: apisix
http:
- name: limit-count-sliding-route
match:
paths:
- /get
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: limit-count-advanced
config:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis
redis_host: "redis-service.aic.svc"
redis_port: 6379
redis_password: "p@ssw0rd"
redis_database: 1
window_type: sliding
sync_interval: 0.2
应用配置:
kubectl apply -f limit-count-advanced-ic.yaml
❶ policy:设置为 redis 以使用 Redis 实例进行速率限制。
❷ redis_host:设置为 Redis 实例的 IP 地址。
❸ redis_port:设置为 Redis 实例的监听端口。
❹ redis_password:如果有,设置为 Redis 实例的密码。
❺ redis_database:设置为 Redis 实例中的数据库编号。
❻ window_type:将窗口类型设置为滑动窗口。
❼ sync_interval:设置同步间隔(可选)。
每隔一秒生成 7 个请求到该路由:
for i in $(seq 7); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done
你应该收到大多数请求的 HTTP/1.1 200 OK 响应,其余为 HTTP 429 Too Many Requests 响应。具体被拒绝的数量取决于第一个请求发送的时间。这验证了配置在不同网关节点上的路由共享相同的配额。
使用 Redis 集群在网关节点之间共享配额
以下示例演示了如何配置 limit-count-advanced 使用滑动窗口算法,并在多个网关节点之间应用相同的配额,从而使不同的网关节点共享相同的速率限制配额。
确保你的 Redis 实例运行在集群模式(Cluster Mode)。limit-count-advanced 插件配置至少需要两个节点。
在网关组中创建一个具有以下配置的路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 1,
"time_window": 30,
"rejected_code": 429,
"key": "remote_addr",
"policy": "redis-cluster",
"redis_cluster_nodes": [
"192.168.xxx.xxx:6379",
"192.168.xxx.xxx:16379"
],
"redis_password": "p@ssw0rd",
"redis_cluster_name": "redis-cluster",
"redis_cluster_ssl": true,
"window_type": "sliding",
"sync_interval": 0.2
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /get
name: limit-count-route
plugins:
limit-count-advanced:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis-cluster
redis_cluster_nodes:
- "192.168.xxx.xxx:6379"
- "192.168.xxx.xxx:16379"
redis_password: "p@ssw0rd"
redis_cluster_name: "redis-cluster"
redis_cluster_ssl: true
window_type: sliding
sync_interval: 0.2
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: limit-count-advanced-plugin-config
spec:
plugins:
- name: limit-count-advanced
config:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis-cluster
redis_cluster_nodes:
- "redis-cluster-0.redis-cluster.aic.svc:6379"
- "redis-cluster-1.redis-cluster.aic.svc:6379"
redis_password: "p@ssw0rd"
redis_cluster_name: "redis-cluster"
redis_cluster_ssl: true
window_type: sliding
sync_interval: 0.2
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: limit-count-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /get
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-advanced-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: limit-count-route
spec:
ingressClassName: apisix
http:
- name: limit-count-route
match:
paths:
- /get
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: limit-count-advanced
config:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis-cluster
redis_cluster_nodes:
- "redis-cluster-0.redis-cluster.aic.svc:6379"
- "redis-cluster-1.redis-cluster.aic.svc:6379"
redis_password: "p@ssw0rd"
redis_cluster_name: "redis-cluster"
redis_cluster_ssl: true
window_type: sliding
sync_interval: 0.2
应用配置:
kubectl apply -f limit-count-advanced-ic.yaml
❶ policy:设置为 redis-cluster 以使用 Redis 集群进行速率限制。
❷ redis_cluster_nodes:设置为 Redis 集群中的 Redis 节点地址。
❸ redis_password:如果有,设置为 Redis 集群的密码。
❹ redis_cluster_name:设置为 Redis 集群名称。
❺ redis_cluster_ssl:启用与 Redis 集群的 SSL/TLS 通信。
❻ window_type:将窗口类型设置为滑动窗口。
❼ sync_interval:设置同步间隔(可选)。
每隔一秒生成 7 个请求到该路由:
for i in $(seq 7); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done
你应该收到大多数请求的 HTTP/1.1 200 OK 响应,其余为 HTTP 429 Too Many Requests 响应。具体被拒绝的数量取决于第一个请求发送的时间。这验证了配置在不同网关节点上的路由共享相同的配额。
自定义速率限制头
以下示例演示了如何使用插件元数据自定义速率限制响应头名称,默认情况下为 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Reset。
本示例假设已存在一条配置了 limit-count-advanced 插件的 /get 路由。
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/limit-count-advanced" -X PUT -d '
{
"log_format": {
"limit_header": "X-Custom-RateLimit-Limit",
"remaining_header": "X-Custom-RateLimit-Remaining",
"reset_header": "X-Custom-RateLimit-Reset"
}
}'
... # 其他 ADC 配置
plugin_metadata:
limit-count-advanced:
limit_header: X-Custom-RateLimit-Limit
remaining_header: X-Custom-RateLimit-Remaining
reset_header: X-Custom-RateLimit-Reset
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
更新 GatewayProxy 清单中的插件元数据:
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
namespace: aic
name: apisix-config
spec:
provider:
type: ControlPlane
controlPlane:
# 在此添加你的控制面连接配置
# ....
pluginMetadata:
limit-count-advanced:
log_format:
limit_header: X-Custom-RateLimit-Limit
remaining_header: X-Custom-RateLimit-Remaining
reset_header: X-Custom-RateLimit-Reset
应用配置:
kubectl apply -f gatewayproxy.yaml
发送请求进行验证:
curl -i "http://127.0.0.1:9080/get"
你应该收到一个 HTTP/1.1 200 OK 响应并看到以下头部:
X-Custom-RateLimit-Limit: 1
X-Custom-RateLimit-Remaining: 0
X-Custom-RateLimit-Reset: 28
使用 Redis Sentinel 在网关节点之间共享配额
以下示例演示了如何使用带有 Redis Sentinel 策略的 limit-count-advanced 插件进行速率限制。
确保你的 Redis 实例运行在 Sentinel 模式。
在网关组中创建一个具有以下配置的路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 1,
"time_window": 30,
"rejected_code": 429,
"key": "remote_addr",
"policy": "redis-sentinel",
"redis_sentinels": [
{"host": "127.0.0.1", "port": 26379},
{"host": "127.0.10.1", "port": 26379},
{"host": "127.0.101.1", "port": 26379}
],
"redis_master_name": "mymaster",
"redis_role": "master",
"sentinel_username": "admin",
"sentinel_password": "admin-password"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /get
name: limit-count-route
plugins:
limit-count-advanced:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis-sentinel
redis_sentinels:
- host: "127.0.0.1"
port: 26379
- host: "127.0.10.1"
port: 26379
- host: "127.0.101.1"
port: 26379
redis_master_name: "mymaster"
redis_role: "master"
sentinel_username: "admin"
sentinel_password: "admin-password"
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: limit-count-advanced-plugin-config
spec:
plugins:
- name: limit-count-advanced
config:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis-sentinel
redis_sentinels:
- host: "redis-sentinel-0.redis-sentinel.aic.svc"
port: 26379
- host: "redis-sentinel-1.redis-sentinel.aic.svc"
port: 26379
- host: "redis-sentinel-2.redis-sentinel.aic.svc"
port: 26379
redis_master_name: "mymaster"
redis_role: "master"
sentinel_username: "admin"
sentinel_password: "admin-password"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: limit-count-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /get
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-advanced-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: limit-count-route
spec:
ingressClassName: apisix
http:
- name: limit-count-route
match:
paths:
- /get
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: limit-count-advanced
config:
count: 1
time_window: 30
rejected_code: 429
key: remote_addr
policy: redis-sentinel
redis_sentinels:
- host: "redis-sentinel-0.redis-sentinel.aic.svc"
port: 26379
- host: "redis-sentinel-1.redis-sentinel.aic.svc"
port: 26379
- host: "redis-sentinel-2.redis-sentinel.aic.svc"
port: 26379
redis_master_name: "mymaster"
redis_role: "master"
sentinel_username: "admin"
sentinel_password: "admin-password"
应用配置:
kubectl apply -f limit-count-advanced-ic.yaml
❶ policy:设置为 redis-sentinel 以使用 Sentinel 模式下的 Redis 进 行速率限制。
❷ redis_sentinels:配置 Sentinel 节点地址列表(主机和端口)。
❸ redis_master_name:配置 Sentinel 监控的 Redis 主组名称。
❹ redis_role:设置为 master 以连接到当前的 Redis 主节点。
❺ sentinel_username:配置用于通过 Redis Sentinel 进行身份验证的用户名。
❻ sentinel_password:配置用于通过 Redis Sentinel 进行身份验证的密码。
每隔一秒生成 5 个请求到该路由:
for i in $(seq 5); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done
你应该在 30 秒窗口内收到一个请求的 HTTP/1.1 200 OK 响应,其余为 HTTP 429 Too Many Requests 响应。
基于规则的速率限制
以下示例演示了如何配置 limit-count-advanced 以根据请求属性应用不同的速率限制规则(从 API7 Enterprise 3.8.17 开始可用)。在此示例中,速率限制基于代表调用者访问层级的 HTTP 头值应用。
请注意,所有规则按顺序应用。如果配置的键不存在,则将跳过相应的规则。
除 HTTP 请求头外,还可以根据其他内置变量配置规则,以实现更灵活、更细粒度的限速策略。
创建一个启用了 limit-count-advanced 插件的路由,该插件根据请求头应用不同的速率限制,允许每个订阅(X-Subscription-ID)进行速率限制,并对试用用户(X-Trial-ID)强制执行更严格的限制:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-rules-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"policy": "local",
"rejected_code": 429,
"rules": [
{
"key": "${http_x_subscription_id}",
"count": "${http_x_custom_count ?? 5}",
"time_window": 60
},
{
"key": "${http_x_trial_id}",
"count": 1,
"time_window": 60
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /get
name: limit-count-rules-route
plugins:
limit-count-advanced:
policy: local
rejected_code: 429
rules:
- key: "${http_x_subscription_id}"
count: "${http_x_custom_count ?? 5}"
time_window: 60
- key: "${http_x_trial_id}"
count: 1
time_window: 60
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: limit-count-advanced-plugin-config
spec:
plugins:
- name: limit-count-advanced
config:
policy: local
rejected_code: 429
rules:
- key: "${http_x_subscription_id}"
count: "${http_x_custom_count ?? 5}"
time_window: 60
- key: "${http_x_trial_id}"
count: 1
time_window: 60
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: limit-count-rules-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /get
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-advanced-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: limit-count-rules-route
spec:
ingressClassName: apisix
http:
- name: limit-count-rules-route
match:
paths:
- /get
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: limit-count-advanced
config:
policy: local
rejected_code: 429
rules:
- key: "${http_x_subscription_id}"
count: "${http_x_custom_count ?? 5}"
time_window: 60
- key: "${http_x_trial_id}"
count: 1
time_window: 60
应用配置:
kubectl apply -f limit-count-advanced-ic.yaml
❶ 使用 X-Subscription-ID 请求头的值作为速率限制键。
❷ 根据 X-Custom-Count 头动态设置请求限制。如果未提供该头,则应用默认计数 5 个请求。
❸ 使用 X-Trial-ID 请求头的值作为速率限制键。
要验证速率限制,使用相同的订阅 ID 生成 7 个请求到该路由:
resp=$(seq 7 | xargs -I{} curl "http://127.0.0.1:9080/get" -H "X-Subscription-ID: sub-123456789" -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": $count_200, "429": $count_429
你应该会看到以下响应,显示当未提供 X-Custom-Count 头时,应用了 5 个请求的默认计数:
200: 5, 429: 2
等待时间窗口重置。使用相同的订阅 ID 生成 5 个请求到该路由,并将 X-Custom-Count 头设置为 3:
resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/get" -H "X-Subscription-ID: sub-123456789" -H "X-Custom-Count: 3" -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": $count_200, "429": $count_429
你应该会看到以下响应,显示 应用了来自 X-Custom-Count 头的 3 个请求的计数:
200: 3, 429: 2
最后,使用相同的试用 ID 生成 3 个请求到该路由:
resp=$(seq 3 | xargs -I{} curl "http://127.0.0.1:9080/get" -H "X-Trial-ID: trial-123456789" -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": $count_200, "429": $count_429
你应该会看到以下响应,显示应用了来自第二条规则的 1 个请求的计数:
200: 1, 429: 2