对 API 应用限流
应用限流可以控制发送到 API 后端的请求数量。这可以保护你的后端免受过多流量的影响,无论这些流量是正常的还是非正常的(例如网络爬虫、DDoS 攻击),这些流量可能会导致运营效率低下和成本增加。
本指南将引导你应用限流来控制在一段时间内发送到上游节点的请求。

前置条件
为所有服务应用限流(不推荐)
你不应该全局配置限流插件,因为不同的 API 通常需要不同的限流配额。如果你在全局(全局规则中)和局部(路由中)配置了相同的插件,API7 网关将按顺序执行这两个插件实例。
为单个路由应用限流
限制请求数
本节将为路由配置限流,使其在 60 秒内仅允许 3 个请求。当超过限制时,将向消费者返回 429 状态码。
- 控制台
- ADC
- Ingress Controller
- 从侧边导航栏中选择网关组的已发布服务,然后点击你想要修改的服务,例如版本为
1.0.0的httpbin。 - 在该已发布服务下,从侧边导航栏中选择路由。
- 选择你的目标路由,例如
get-ip。 - 在插件字段中,点击新增插件。
- 搜索
limit-count插件,然后点击新增。 - 在对话框中,执行以下操作:
-
将以下配置添加到 JSON 编辑器中:
{
"count": 3,
"time_window": 60,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Too many requests",
"policy": "local",
"allow_degradation": false,
"show_limit_quota_header": true
}
如果你想引用 Secret 提供者(Secret Provider),请参阅在 HashiCorp Vault 中引用 Secret 和在 AWS Secrets Manager 中引用 Secret,并使用以下包含 secret 的配置替代:
{
"count": 3,
"time_window": 60,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Too many requests",
"policy": "redis",
"redis_host": "127.0.0.1",
"redis_port": 6379,
"redis_username": "$secret://vault/my-vault/redis/username",
"redis_password": "$secret://vault/my-vault/redis/password",
"redis_database": 1,
"redis_timeout": 1001,
"allow_degradation": false,
"show_limit_quota_header": true
}
- 点击新增。
下面是一个交互式演示,提供了有关限制请求数量的实践介绍。通过点击并按照步骤操作,你将更好地了解如何在 API7 企业版中使用它。
要使用 ADC 配置该路由,请创建以下配置:
services:
- name: httpbin
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- uris:
- /ip
name: get-ip
methods:
- GET
plugins:
limit-count:
_meta:
disable: false
count: 3
time_window: 60
key_type: var
key: remote_addr
policy: local
rejected_code: 429
rejected_msg: Too many requests
allow_degradation: false
show_limit_quota_header: true
将配置同步到 API7 企业版:
adc sync -f adc.yaml
API7 Ingress Controller 目前不支持在单个路由上启用插件。作为替代,你可以创建一个新服务,并在该服务上启用限流插件。
创建一个路由的 Kubernetes 资源清单文件(该文件也会创建一个服务)并启用 limit-count:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: api7
name: limit-count-plugin-config
spec:
plugins:
- name: limit-count
config:
count: 3
time_window: 60
key_type: var
key: remote_addr
rejected_code: 429
rejected_msg: "Too many requests"
policy: local
allow_degradation: false
show_limit_quota_header: true
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: api7
name: get-ip
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /ip
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-plugin-config
backendRefs:
- name: httpbin
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: api7
name: httpbin
spec:
ingressClassName: apisix
http:
- name: get-ip
match:
paths:
- /ip
backends:
- serviceName: httpbin
servicePort: 80
plugins:
- name: limit-count
enable: true
config:
count: 3
time_window: 60
key_type: var
key: remote_addr
rejected_code: 429
rejected_msg: "Too many requests"
policy: local
allow_degradation: false
show_limit_quota_header: true
将配置应用到你的集群:
kubectl apply -f httpbin-route-rate-limiting.yaml
验证
要进行验证,请连续发送五个请求:
resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/ip" -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
你应该会看到以下响应,表明在 5 个请求中,有 3 个请求成功(状态码 200),而其余的被拒绝(状态码 429)。
200: 3, 429: 2
限制每秒请求数
本节为路由配置限流,使其每秒仅允许 1 个请求。当每秒请求数在 1 到 3 之间时,它们将被延迟/节流。当每秒请求数超过 3 个时,将返回 429 状态码。
- 控制台
- ADC
- Ingress Controller
- 从侧边导航栏中选择网关组的已发布服务,然后选择你想要修改的服务,例如版本为
1.0.0的httpbin。 - 在该已发布服务下,从侧边导航栏中选择路由。
- 选择你的目标路由,例如
get-ip。 - 在插件字段中,点击新增插件。
- 搜索
limit-req插件,然后点击新增。 - 在对话框中,执行以下操作:
-
将以下配置添加到 JSON 编辑器中:
{
"rate": 1,
"burst": 2,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Requests are too frequent, please try again later."
} -
点击新增。
要使用 ADC 配置该路由,请创建以下配置:
services:
- name: httpbin
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- uris:
- /ip
name: get-ip
methods:
- GET
plugins:
limit-req:
_meta:
disable: false
rate: 1
burst: 2
key_type: var
key: remote_addr
rejected_code: 429
rejected_msg: Requests are too frequent, please try again later.
将配置同步到 API7 网关:
adc sync -f adc.yaml
API7 Ingress Controller 目前不支持在单个路由上启用插件。作为替代,你可以创建一个新服务,并在该服务上启用限流插件。
创建一个路由的 Kubernetes 资源清单文件(该文件也会创建一个服务)并启用 limit-req:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: api7
name: limit-req-plugin-config
spec:
plugins:
- name: limit-req
config:
rate: 1
burst: 2
key_type: var
key: remote_addr
rejected_code: 429
rejected_msg: "Requests are too frequent, please try again later."
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: api7
name: get-ip
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /ip
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-req-plugin-config
backendRefs:
- name: httpbin
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: api7
name: httpbin
spec:
ingressClassName: apisix
http:
- name: get-ip
match:
paths:
- /ip
backends:
- serviceName: httpbin
servicePort: 80
plugins:
- name: limit-req
enable: true
config:
rate: 1
burst: 2
key_type: var
key: remote_addr
rejected_code: 429
rejected_msg: "Requests are too frequent, please try again later."
将配置应用到你的集群:
kubectl apply -f httpbin-route-rate-limiting.yaml
验证
要进行验证,请向该路由发送三个请求:
resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/ip" -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 更新为 0,然后向该路由发送三个请求:
resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/ip" -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
为消费者限流
以下示例演示了如何为普通消费者和匿名消费者配置不同的限流策略,其中匿名消费者无需进行身份验证且配额较少。虽然此示例使用 Key Auth 插件进行身份验证,但匿名消费者也可以通过 Basic Auth 插件、JWT Auth 插件和 HMAC Auth 插件进行配置。
添加普通消费者
创建一个带有密钥认证凭据的普通消费者 Alice,并配置 Limit Count 插件,允许在 60 秒的窗口期内有 3 个配额:
- 控制台
- ADC
- Ingress Controller
- 从侧边导航栏中选择网关组的消费者。
- 点击新增消费者。
- 在对话框中,执行以下操作:
- 在名称字段中,输入
Alice。 - 点击新增。
- 在认证凭据选项卡下,点击新增 Key Authentication 凭据。
- 在对话框中,执行以下操作:
- 在名称字段中,输入
alice-key。 - 在 Key 字段中,选择手动输入,然后输入
alice-key。- 如果你想从 Secret 提供者引用,请参阅在 HashiCorp Vault 中引用 Secret 或 在 AWS Secrets Manager 中引用 Secret。
- 点击新增。
- 转到插件选项卡,点击新增插件。
- 搜索
limit-count插件,然后点击新增。 - 在对话框中,执行以下操作:
-
将以下配置添加到 JSON 编辑器中:
{
"count": 3,
"time_window": 60,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Too many requests",
"policy": "local",
"allow_degradation": false,
"show_limit_quota_header": true
} -
点击新增。
要使用 ADC 创建消费者,请创建以下配置:
consumers:
- username: Alice
credentials:
- name: alice-key
type: key-auth
config:
key: alice-key
plugins:
limit-count:
allow_degradation: false
count: 3
key: remote_addr
key_type: var
policy: local
rejected_code: 429
rejected_msg: Too many requests
show_limit_quota_header: true
time_window: 60
将配置同步到 API7 企业版:
adc sync -f adc-reg-consumer.yaml
为消费者 alice 创建 Kubernetes 资源清单文件,包含用于密钥认证的一个主密钥和一个备用密钥:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
namespace: api7
name: alice
spec:
gatewayRef:
name: apisix
credentials:
- type: key-auth
name: alice-key
config:
key: alice-key
plugins:
- name: limit-count
config:
count: 3
time_window: 60
key: remote_addr
key_type: var
policy: local
rejected_code: 429
rejected_msg: Too many requests
show_limit_quota_header: true
allow_degradation: false
将配置应用到你的集群:
kubectl apply -f consumer-rate-limit.yaml
ApisixConsumer CRD 目前不支持在消费者上配置插件。
添加匿名消费者
创建一个匿名消费者 anonymous,并配置 Limit Count 插件,允许在 60 秒的窗口期内有 1 个配额:
- 控制台
- ADC
- Ingress Controller
- 从侧边导航栏中选择网关组的消费者。
- 点击新增消费者。
- 在对话框中,执行以下操作:
- 在名称字段中,输入
anonymous。 - 点击新增。
- 转到插件选项卡,点击新增插件。
- 搜索
limit-count插件,然后点击新增。 - 在对话框中,执行以下操作:
-
将以下配置添加到 JSON 编辑器中:
{
"count": 1,
"time_window": 60,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Too many requests",
"policy": "local",
"allow_degradation": false,
"show_limit_quota_header": true
} -
点击新增。
要使用 ADC 创建匿名消费者,请创建以下配置:
consumers:
- username: anonymous
plugins:
limit-count:
allow_degradation: false
count: 1
key: remote_addr
key_type: var
policy: local
rejected_code: 429
rejected_msg: Too many requests
show_limit_quota_header: true
time_window: 60
将配置同步到 API7 企业版:
adc sync -f adc-reg-consumer.yaml -f adc-anon-consumer.yaml
为匿名消费者创建另一个 Kubernetes 资源清单文件并启用限流:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
namespace: api7
name: anonymous
spec:
gatewayRef:
name: apisix
plugins:
- name: limit-count
config:
count: 1
time_window: 60
key: remote_addr
key_type: var
policy: local
rejected_code: 429
rejected_msg: Too many requests
show_limit_quota_header: true
allow_degradation: false
将配置应用到你的集群:
kubectl apply -f anon-consumer-rate-limit.yaml
ApisixConsumer CRD 目前不支持在消费者上配置插件。
配置路由
创建一个路由,并配置 Key Auth 插件允许匿名消费者 anonymous 绕过身份验证:
- 控制台
- ADC
- Ingress Controller
- 从侧边导航栏中选择网关组的已发布服务,然后点击你想要修改的服务,例如版本为
1.0.0的httpbin。 - 在该已发布服务下,从侧边导航栏中选择路由。
- 选择你的目标路由,例如
get-ip。 - 在插件字段中,点击新增插件。
- 搜索
key-auth插件,然后点击新增。 - 在对话框中,执行以下操作:
-
将以下配置添加到 JSON 编辑器中:
{
"anonymous_consumer": "anonymous"
} -
点击新增。
要使用 ADC 配置该路由,请创建以下配置:
services:
- name: httpbin
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- uris:
- /ip
name: get-ip
methods:
- GET
plugins:
key-auth:
_meta:
disable: false
anonymous_consumer: anonymous
将配置同步到 API7 网关:
adc sync -f adc-reg-consumer.yaml -f adc-anon-consumer.yaml -f adc-route.yaml
更新带有匿名消费者的路由清单文件:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: api7
name: anon-key-auth-plugin-config
spec:
plugins:
- name: key-auth
config:
anonymous_consumer: api7_anonymous
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: api7
name: get-ip
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /ip
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: anon-key-auth-plugin-config
backendRefs:
- name: httpbin
port: 80
❶ Ingress Controller 创建的实际消费者名称会以你的命名空间为前缀。请确保相应地更新 anonymous_consumer 名称。
将配置应用到你的集群:
kubectl apply -f anon-rate-limit-route.yaml
ApisixConsumer CRD 目前不支持在消费者上配置插件;因此,省略此步骤。
验证
要进行验证,请使用 Alice 的 key 连续发送五个请求:
resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/ip" -H 'apikey: alice-key' -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
你应该会看到以下响应,表明在 5 个请求中,有 3 个请求成功(状态码 200),而其余的被拒绝(状态码 429)。
200: 3, 429: 2
发送五个匿名请求:
resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/ip" -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
你应该会看到以下响应,表明只有一个请求成功:
200: 1, 429: 4