

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 执行速率限制
<a name="gateway-rate-limits-enforcement"></a>

本主题介绍网关如何在运行时评估和强制执行速率限制，包括与其他网关功能的交互、受限的响应格式和可观察性。

## 与网关规则的交互
<a name="gateway-rate-limits-enforcement-rules-interaction"></a>

网关先评估速率限制，**然后再**评估网关规则。如果速率限制限制了请求，则该请求永远不会到达规则评估阶段。

## 堆叠语义
<a name="gateway-rate-limits-enforcement-stacking"></a>

当一个请求适用多个速率限制时，网关使用 AND 逻辑 — 必须通过所有速率限制才能继续请求。如果有任何单速率限制拒绝请求，则网关会对其进行限制。

## 条目匹配和特异性
<a name="gateway-rate-limits-enforcement-entry-matching"></a>

当速率限制有多个条目时，网关会为已解析的维度值选择最具体的匹配条目：
+ 精确值匹配优先于`*`条目。
+ 该`*`值表示 “将此比率应用于该维度的所有值” ——它充当默认条目。
+ 对于多维度速率限制，网关使用渐进式尾随回退：它首先尝试完全精确匹配，然后将尾随维度逐`*`一替换，直到找到匹配项。

以下示例显示了当解析值为`dimensionKeys: ["targetName", "toolName"]`时，如何将条目与速率限制进行匹配`["my-target", "readData"]`：


| 入口尺寸 | 火柴？ | 为什么 | 
| --- | --- | --- | 
|  `{"targetName": "my-target", "toolName": "readData"}`  | 是（先勾选） | 两个维度都完全匹配。最具体。 | 
|  `{"targetName": "my-target", "toolName": "*"}`  | 是（先勾选） | 在第一个维度上精确匹配，`*`在第二个维度上完全匹配。 | 
|  `{"targetName": "", "toolName": ""}`  | 是（上次勾选） | 默认条目。最不具体。 | 

第一个匹配的参赛作品获胜。如果没有匹配的条目（且不存在`*`默认值），则会跳过该请求的速率限制。

## 评估顺序
<a name="gateway-rate-limits-enforcement-evaluation-order"></a>

网关按以下顺序评估速率限制：

1. 网关首先使用更多的维度密钥评估速率限制（优先考虑更具体的限制）。

1. 在相同数量的维度内，网关首先使用更严格（更低）的速率评估速率限制。

1. 第一次拒绝时评估会短路 — 网关不评估剩余的速率限制。

## 与服务管理限制的交互
<a name="gateway-rate-limits-enforcement-service-limits"></a>

网关强制执行客户定义的速率限制和服务管理的限制。任何请求的有效费率均为两者中的最低值：
+ 网关首先评估客户定义的速率限制。
+ 如果请求超过客户限制，则会评估服务管理限制。
+ 来自任何一个来源的拒绝都会导致限制。

## 受限的响应
<a name="gateway-rate-limits-enforcement-throttled-responses"></a>

当请求受到限制时，网关会返回一个特定于协议的错误响应，其中包含响应正文中的`retryAfter`值。

 **HTTP 协议：**

```
{
    "error": "Rate limit exceeded",
    "success": false,
    "limitKey": "rl-abc123/targetName=my-target",
    "metric": "requests",
    "retryAfter": 1
}
```

 **MCP 协议 (JSON-RPC):** 

```
{
    "jsonrpc": "2.0",
    "id": "request-1",
    "error": {
        "code": -32003,
        "message": "Rate limit exceeded",
        "data": {
            "limitKey": "rl-abc123/targetName=my-target",
            "metric": "requests",
            "retryAfter": 1
        }
    }
}
```

 **OpenAI-compatible 协议：**

```
{
    "error": {
        "message": "Rate limit exceeded",
        "type": "rate_limit_error",
        "code": "429",
        "limitKey": "rl-abc123/qualifiedModelId=anthropic.claude-3-sonnet",
        "metric": "tokens",
        "retryAfter": 60
    }
}
```

 **Anthropic-compatible 协议：**

```
{
    "type": "error",
    "error": {
        "type": "rate_limit_error",
        "message": "Rate limit exceeded",
        "limitKey": "rl-abc123/qualifiedModelId=anthropic.claude-3-sonnet",
        "metric": "tokens",
        "retryAfter": 60
    }
}
```

该`retryAfter`字段指示呼叫者在重试之前应等待多少秒。直接在客户端重试逻辑中使用此值。

## 传播时机
<a name="gateway-rate-limits-enforcement-propagation"></a>

速率限制更改（创建、更新、删除）将在 30 秒内传播到数据平面。传播期间：
+ 在传播完成之前，不会强制执行新的速率限制。
+ 更新后的速率限制会继续强制执行先前的配置，直到更新传播为止。
+ 删除的速率限制将继续执行，直到删除行为传播开来。

## 执法的准确性和最终一致性
<a name="gateway-rate-limits-enforcement-accuracy"></a>

速率限制的实施**最终是一致**的，而不是精确的。在限制开始接收流量后的那一刻，执法精度是近似值，并且随着流量的持续而提高。因此，您观察到的准确性取决于您的交通模式。

预计会出现以下行为：
+  **起初冷限制过度接受。**冷限制是指新创建的或最近没有流量的限制。在很短的初始时间内，网关可能会在强制收敛之前超额接受（允许的请求数超过配置的速率）。一旦限制低于持续流量，精度就会提高，观察到的油门速率将接近配置的速率。
+  **持续的流量会准确执行，但短暂的流量可能不会。**突破冷极限的短暂爆发可以在不被限制的情况下通过。由于随着限制的升温，准确性会提高，因此发送的速率与持续流量相同。要观察或演示执法情况，请将持续流量发送到限制几分钟，而不是一次短暂的爆发。例如，对于每秒 4 个请求的限制，网关可能不会在第一秒钟限制第 5 个请求。如果您每秒连续发送 5 个请求，则在限制预热后，您将始终看到额外的请求被限制。
+  **非常低的比率不太准确。**低于每秒大约 1 个请求的速率（例如，每分钟请求数限制很小）更难精确执行，而且会显示出更大的可变性。在精确的执法很重要的情况下，更倾向于更高的费率，并将非常低的限额视为近似值。
+  **代币限额的收敛速度更慢。** Token-per-minute 只有在模型做出响应后，限制才会更新（协调）跟踪的使用总量。在运行几秒钟或几分钟的请求完成之前，仅保留其预估成本和预算。相对于请求限制，这延长了网关可能超额接受请求的窗口。有关详细信息，请参阅[代币速率限制常见问题解答](gateway-rate-limits-best-practices.md#gateway-rate-limits-best-practices-tpm-faq)。

围绕合理使用和后端保护设计您的限制。这意味着要在持续的窗口内平滑爆发并保护目标免受邻居噪音的侵害，而不是在超过阈值的那一刻屏蔽确切的请求号。速率限制不是一个精确、精确的门槛。如下一节所述，速率限制也不是安全边界。

## Fail-open 行为
<a name="gateway-rate-limits-enforcement-fail-open"></a>

网关使用失效开放语义进行速率限制评估。下表描述了速率限制系统遇到错误时的行为：


| 场景 | 决策 | 理由 | 
| --- | --- | --- | 
| 速率限制服务超时 | 允许 | 可用性优先于强制执行。 | 
| 维度密钥无法从请求中解析 | 跳过（允许） | 速率限制不适用于此请求类型。 | 
| 速率限制缓存刷新失败 | 使用陈旧的数据重试 | 在缓存恢复之前使用最新的已知配置。 | 

**重要**  
由于失效开放行为，请不要仅仅依赖速率限制作为安全边界。对流量管理和服务质量使用速率限制，使用身份验证、授权和 WAF 规则进行安全执行。

## 使用 OpenTelemetry 跨度进行追踪
<a name="gateway-rate-limits-enforcement-tracing"></a>

对于每个评估客户速率限制的请求，网关都会在服务器跨度上发出 OpenTelemetry (OTEL) 跨度属性。使用这些属性进行调试和监控。


| 属性 | 说明 | 示例 | 
| --- | --- | --- | 
|  `aws.agentcore.gateway.throttle.customer.decision`  | 该请求的执行决定。 |  `allowed` 或 `throttled`  | 
|  `aws.agentcore.gateway.throttle.customer.limit_key`  | 拒绝请求`rateLimitId`的速率限制中的一个。只有在做出决定时才在场`throttled`。 |  `per-target-rps`  | 
|  `aws.agentcore.gateway.throttle.customer.metric`  | 已用尽的指标类型。只有在做出决定时才在场`throttled`。 |  `requests`  | 
|  `aws.agentcore.gateway.throttle.customer.matched_entry`  | Comma-separated 已解析触发限制的条目的维度值。只有在做出决定时才在场`throttled`。 |  `my-target,alice`  | 
|  `aws.agentcore.gateway.throttle.customer.resolved_values`  | Comma-separated 按`dimensionKeys`顺序从触发限制的请求中解析的实际维度值。与`matched_entry`（它反映匹配条目的配置值，包括任何值`*`）不同，此属性反映的是运行时解析的具体值。只有在做出决定时才在场`throttled`。 |  `my-target,alice`  | 
|  `aws.agentcore.gateway.throttle.customer.evaluated`  | 为该请求检查的所有速率限制存储桶的排序列表。每个条目都显示速率限制 ID、指标和已解析的维度值。两者兼`allowed`而有`throttled`之。 |  `["per-target-rps:requests:my-target", "per-caller-rpm:requests:alice"]`  | 

该`evaluated`属性对于了解哪些速率限制适用于请求非常有用，即使请求被允许也是如此。列表中的每个条目都遵循格式`{rateLimitId}:{metric}:{resolvedDimVal1,dimVal2,…​}`。