跳到主要内容
版本:3.2.16.4

API 限流限速

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

本指南将引导你应用速率限制来控制随时间推移发送到上游节点的请求。

速率限制

前提条件

  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 提供商中的密钥,请参阅 引用 HashiCorp Vault 中的密钥引用 AWS Secrets Manager 中的密钥,并使用以下带有密钥的配置:

    {
    "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 插件 配置匿名消费者。

新增普通消费者

创建一个具有 Key Authentication凭据的常规消费者 Alice,并将 Limit Count 插件 配置为允许在 60 秒窗口内使用 3 个配额:

  1. 从侧边栏选择网关组的消费者

  2. 点击新增消费者

  3. 在对话框中,执行以下操作:

    • 名称字段中,输入 Alice
    • 点击新增
  4. 凭据选项卡下,点击新增Key Authentication凭据

  5. 在对话框中,执行以下操作:

  6. 转到插件选项卡,点击启用插件

  7. 搜索 limit-count 插件,然后点击启用

  8. 在对话框中,执行以下操作:

    • 将以下配置新增到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
    • 点击新增
  4. 转到插件选项卡,点击启用插件

  5. 搜索 limit-count 插件,然后点击启用

  6. 在对话框中,执行以下操作:

    • 将以下配置新增到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 的密钥发送五个连续的请求:

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

相关阅读