a6-plugin-limit-count
概述
limit-count 插件使用固定窗口计 数器算法对请求进行限流。通过 count 定义 time_window 时间间隔内允许的最大请求数。它支持按 IP、消费者、请求头或自定义变量设置键。在分布式 Apache APISIX部署中,请使用 Redis 或 Redis 集群作为共享计数器后端。
适用场景
- 简单请求计数,例如每小时 100 个请求。
- 按消费者或 API 密钥实施 API 配额。
- 通过 Redis 在多个 Apache APISIX节点间共享限流。
- 在多个路由间共享分组配额。
插件配置参考
核心字段
| 字段 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
count | integer | 是* | — | 时间窗口内允许的最大请求数,必须大于 0 |
time_window | integer | 是* | — | 以秒为单位的时间窗口,必须大于 0 |
key_type | string | 否 | "var" | 键类型:"var"、"var_combination" 或 "constant" |
key | string | 否 | "remote_addr" | 用于计数的变量名称或变量组合 |
rejected_code | integer | 否 | 503 | 拒绝请求时的 HTTP 状态码(200 至 599) |
rejected_msg | string | 否 | — | 自定义拒绝消息正文 |
group | string | 否 | — | 在具有相同组 ID 的路由间共享计数器 |
policy | string | 否 | "local" | 存储策略:"local"、"redis" 或 "redis-cluster" |
show_limit_quota_header | boolean | 否 | true | 在响应中包含 X-RateLimit-* 请求头 |
allow_degradation | boolean | 否 | false | 插件失败时是否允许请求通过 |
*除非使用 rules 数组,否则为必填项。
Redis 字段(policy: "redis" 时)
| 字段 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
redis_host | string | 是 | — | Redis 服务器地址 |
redis_port | integer | 否 | 6379 | Redis 端口 |
redis_username | string | 否 | — | Redis ACL 用户名 |
redis_password | string | 否 | — | Redis 密码 |
redis_database | integer | 否 | 0 | Redis 数据库索引 |
redis_timeout | integer | 否 | 1000 | 以毫秒为单位的超时时间 |
redis_ssl | boolean | 否 | false | 是否为 Redis 启用 TLS |
Redis 集群字段(policy: "redis-cluster" 时)
| 字段 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
redis_cluster_nodes | 字符串数组 | 是 | — | "host:port" 数组,至少两个节点 |
redis_cluster_name | string | 是 | — | 集群名称 |
redis_password | string | 否 | — | 集群密码 |
redis_timeout | integer | 否 | 1000 | 以毫秒为单位的超时时间 |
redis_cluster_ssl | boolean | 否 | false | 是否启用 TLS |
键类型
key_type | key 格式 | 示例 | 描述 |
|---|---|---|---|
"var" | NGINX 变量(不带 $) | "remote_addr" | 单个变量 |
"var_combination" | $var1 $var2 | "$remote_addr $consumer_name" | 组合多个变量 |
"constant" | 任意字符串 | "global" | 所有请求使用同一计数器 |
响应头
当 show_limit_quota_header: true(默认值)时:
| 请求头 | 描述 |
|---|---|
X-RateLimit-Limit | 时间窗口内的总配额 |
X-RateLimit-Remaining | 当前窗口内剩余的请求数 |
X-RateLimit-Reset | 距离计数器重置的秒数 |
分步操作:基础限流
1. 按客户端 IP 限流(路由级)
a6 route create -f - <<'EOF'
{
"id": "rate-limited-api",
"uri": "/api/*",
"plugins": {
"limit-count": {
"count": 100,
"time_window": 60,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Rate limit exceeded. Try again later."
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF
每个客户端 IP 每 60 秒允许 100 个请求。
2. 按消费者限流
a6 consumer create -f - <<'EOF'
{
"username": "free-tier",
"plugins": {
"limit-count": {
"count": 100,
"time_window": 3600,
"rejected_code": 429
}
}
}
EOF
a6 consumer create -f - <<'EOF'
{
"username": "premium",
"plugins": {
"limit-count": {
"count": 10000,
"time_window": 3600,
"rejected_code": 429
}
}
}
EOF
消费者级限制适用于该消费者访问的所有路由。
常见模式
在路由间共享配额(组)
{
"plugins": {
"limit-count": {
"count": 1000,
"time_window": 3600,
"group": "api-v1",
"rejected_code": 429
}
}
}
所有配置 "group": "api-v1" 的路由共享同一个每小时 1000 个请求的计数器。
**重要:**同一组中的所有路由必须使用完全相同的 limit-count 配置。
多变量键(IP 加消费者)
{
"plugins": {
"limit-count": {
"count": 50,
"time_window": 60,
"key_type": "var_combination",
"key": "$remote_addr $consumer_name",
"rejected_code": 429
}
}
}