跳到主要内容
版本:3.9.x

对 API 应用限流

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

本指南将引导你应用限流来控制在一段时间内发送到上游节点的请求。

Rate Limiting

前置条件

  1. 安装 API7 企业版
  2. 在网关组上有一个运行中的 API

为所有服务应用限流(不推荐)

你不应该全局配置限流插件,因为不同的 API 通常需要不同的限流配额。如果你在全局(全局规则中)和局部(路由中)配置了相同的插件,API7 网关将按顺序执行这两个插件实例。

为单个路由应用限流

限制请求数

本节将为路由配置限流,使其在 60 秒内仅允许 3 个请求。当超过限制时,将向消费者返回 429 状态码。

  1. 从侧边导航栏中选择网关组的已发布服务,然后点击你想要修改的服务,例如版本为 1.0.0httpbin
  2. 在该已发布服务下,从侧边导航栏中选择路由
  3. 选择你的目标路由,例如 get-ip
  4. 插件字段中,点击新增插件
  5. 搜索 limit-count 插件,然后点击新增
  6. 在对话框中,执行以下操作:
  • 将以下配置添加到 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 企业版中使用它。

验证

要进行验证,请连续发送五个请求:

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 状态码。

  1. 从侧边导航栏中选择网关组的已发布服务,然后选择你想要修改的服务,例如版本为 1.0.0httpbin
  2. 在该已发布服务下,从侧边导航栏中选择路由
  3. 选择你的目标路由,例如 get-ip
  4. 插件字段中,点击新增插件
  5. 搜索 limit-req 插件,然后点击新增
  6. 在对话框中,执行以下操作:
  • 将以下配置添加到 JSON 编辑器中:

    {
    "rate": 1,
    "burst": 2,
    "key_type": "var",
    "key": "remote_addr",
    "rejected_code": 429,
    "rejected_msg": "Requests are too frequent, please try again later."
    }
  • 点击新增

验证

要进行验证,请向该路由发送三个请求:

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 个配额:

  1. 从侧边导航栏中选择网关组的消费者
  2. 点击新增消费者
  3. 在对话框中,执行以下操作:
  • 名称字段中,输入 Alice
  • 点击新增
  1. 认证凭据选项卡下,点击新增 Key Authentication 凭据
  2. 在对话框中,执行以下操作:
  1. 转到插件选项卡,点击新增插件
  2. 搜索 limit-count 插件,然后点击新增
  3. 在对话框中,执行以下操作:
  • 将以下配置添加到 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
    }
  • 点击新增

添加匿名消费者

创建一个匿名消费者 anonymous,并配置 Limit Count 插件,允许在 60 秒的窗口期内有 1 个配额:

  1. 从侧边导航栏中选择网关组的消费者
  2. 点击新增消费者
  3. 在对话框中,执行以下操作:
  • 名称字段中,输入 anonymous
  • 点击新增
  1. 转到插件选项卡,点击新增插件
  2. 搜索 limit-count 插件,然后点击新增
  3. 在对话框中,执行以下操作:
  • 将以下配置添加到 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
    }
  • 点击新增

配置路由

创建一个路由,并配置 Key Auth 插件允许匿名消费者 anonymous 绕过身份验证:

  1. 从侧边导航栏中选择网关组的已发布服务,然后点击你想要修改的服务,例如版本为 1.0.0httpbin
  2. 在该已发布服务下,从侧边导航栏中选择路由
  3. 选择你的目标路由,例如 get-ip
  4. 插件字段中,点击新增插件
  5. 搜索 key-auth 插件,然后点击新增
  6. 在对话框中,执行以下操作:
  • 将以下配置添加到 JSON 编辑器中:

    {
    "anonymous_consumer": "anonymous"
    }
  • 点击新增

验证

要进行验证,请使用 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

附加资源