目 录CONTENT

文章目录

掌握 Amazon Bedrock 限制和可用性:全面指南

Administrator
2026-02-12 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

📢 转载信息

原文链接:https://aws.amazon.com/blogs/machine-learning/mastering-amazon-bedrock-throttling-and-service-availability-a-comprehensive-guide/

原文作者:Farzin Bagheri, Abel Laura, Arun Km, and Aswath Ram A Srinivasan


在生产的生成式AI应用中,我们时常会遇到一系列错误,其中最常见的是返回 429 ThrottlingException503 ServiceUnavailableException 错误的请求失败。作为一个业务应用,这些错误可能由于应用架构中的多个层次而发生。

大多数情况下,这些错误是可重试的,但这会影响用户体验,因为对应用的调用会延迟。响应延迟会扰乱对话的自然流程,降低用户兴趣,并最终阻碍AI驱动的解决方案在交互式AI应用中的广泛采用。

最常见的挑战之一是多个用户同时对单个模型进行广泛的应用调用。掌握这些错误意味着应用是稳健的还是让用户感到沮丧之间的区别。

本文将向您展示如何实施稳健的错误处理策略,以帮助在使用 Amazon Bedrock 时提高应用程序的可靠性和用户体验。我们将深入探讨优化应用程序性能以应对这些错误的策略。无论您是针对全新的应用程序还是成熟的AI应用程序,在这篇文章中,您都将找到针对这些错误进行操作的实用指南。

前提条件

  • 拥有Amazon Bedrock访问权限的AWS账户
  • 安装了 Python 3.x 和 boto3
  • 对AWS服务的基本了解
  • IAM 权限:确保您具有以下最低权限:
    • 针对您的特定模型的 bedrock:InvokeModelbedrock:InvokeModelWithResponseStream
    • 用于监控的 cloudwatch:PutMetricData, cloudwatch:PutMetricAlarm
    • 如果使用SNS通知,则为 sns:Publish
    • 遵循最小权限原则 – 只授予用例所需的权限

示例 IAM 策略:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:InvokeModel" ], "Resource": "arn:aws:bedrock:us-east-1:123456789012:model/anthropic.claude-*" } ]
}

注意: 本演练使用可能会产生费用的AWS服务,包括用于监控的 Amazon CloudWatch 和用于通知的 Amazon SNS。详情请参阅AWS定价页面。

快速参考:503 与 429 错误

下表比较了这两种错误类型:

方面 503 ServiceUnavailable (服务不可用) 429 ThrottlingException (限流异常)
主要原因 临时服务容量问题,服务器故障 超出了账户配额(RPM/TPM)
与配额相关 与配额无关 直接与配额相关
解决时间 瞬态,刷新更快 需要等待配额刷新
重试策略 带有指数退避的即时重试 必须与60秒配额周期同步
用户操作 等待并重试,考虑替代方案 优化请求模式,增加配额

深入研究 429 ThrottlingException

429 ThrottlingException 意味着 Amazon Bedrock 正在故意拒绝您的部分请求,以确保总体使用量保持在您配置或默认分配的配额之内。在实践中,您最常会看到三种限流情况:基于速率、基于令牌和特定于模型的限流。

1. 基于速率的限流(RPM – 每分钟请求数)

错误消息:

ThrottlingException: Too many requests, please wait before trying again.

或者:

botocore.errorfactory.ThrottlingException: An error occurred (ThrottlingException) when calling the InvokeModel operation: Too many requests, please wait before trying again

这实际指示了什么

基于速率的限流是在发送到给定模型和区域的每分钟总 Bedrock 请求数超过您账户的 RPM 配额时触发的。关键细节是,此限制在调用方之间强制执行,而不仅仅是针对单个应用程序或微服务。

想象一下咖啡店的一个共享队列:哪个团队排队并不重要;咖啡师每分钟只能制作固定数量的饮料。一旦加入队列的人数超过咖啡师可以处理的数量,一些顾客就会被告知稍后再回来。这条“稍后再回来”的消息就是您的 429。

多应用高峰场景

假设您有三个生产应用程序,它们都在同一区域调用相同的 Bedrock 模型:

  • 应用 A 通常的峰值约为每分钟 50 个请求。
  • 应用 B 的峰值也约为 50 rpm。
  • 应用 C 在其自身高峰期通常运行在约 50 rpm。

运维部门已请求此模型的配额为 150 RPM,这看起来很合理,因为 50 + 50 + 50 = 150,并且历史仪表板显示每个应用都保持在预期的峰值水平。

然而,在现实中,您的流量不是完美平稳的。也许在闪购或营销活动期间,应用 A 的 RPM 瞬间飙升至 60,而 B 和 C 保持在 50。该分钟的总和变为 160 rpm,超过了您的 150 rpm 配额,一些请求开始以 ThrottlingException 失败。

当三个应用在更长的时间内同时向上移动时,您也可能遇到麻烦。想象一种新的模式,高峰流量如下所示:

  • 应用 A: 75 rpm
  • 应用 B: 50 rpm
  • 应用 C: 50 rpm

您的新真实峰值为 175 rpm,即使原始配额是按 150 设计的。在这种情况下,您将在那些高峰时段定期看到 429 错误,即使平均日流量仍然看起来“正常”。

缓解策略

对于基于速率的限流,缓解措施有两个方面:客户端行为和配额管理。

在客户端方面:

  • 实施请求速率限制,以限制每个应用程序每秒或每分钟可以发送的调用次数。API、SDK 包装器或 API 网关等服务网格可以强制执行每个应用的预算,这样单个“嘈杂的”客户端就不会使其他客户端挨饿。
  • 在 429 错误上使用带抖动的指数退避(exponential backoff with jitter),这样重试的频率可以逐渐降低,并且跨实例去同步。
  • 将重试窗口与配额刷新周期对齐:由于 RPM 是按 60 秒窗口强制执行的,重试发生在下一分钟开始几秒后更有可能成功。

在配额方面:

  • 分析每个应用程序的 CloudWatch 指标,以确定真实的峰值 RPM,而不是仅仅依赖平均值。
  • 对同一模型/区域的所有应用的峰值进行汇总,加上安全裕度,如果需要,通过 AWS 服务配额请求增加 RPM。

在前面的示例中,如果应用 A 峰值为 75 rpm,而 B 和 C 峰值为 50 rpm,您应该计划至少 175 rpm,并且现实目标是 200 rpm 左右,以便为增长和意外突发留出空间。

2. 基于令牌的限流(TPM – 每分钟令牌数)

错误消息:

botocore.errorfactory.ThrottlingException: An error occurred (ThrottlingException) when calling the InvokeModel operation: Too many tokens, please wait before trying again.

令牌限制为何重要

即使您的请求数量适中,单个大的提示或生成长输出的模型也会一次消耗数千个令牌。当每分钟处理的输入和输出令牌总数超过您账户对该模型的 TPM 配额时,就会发生基于令牌的限流。

例如,一个每分钟发送 10 个请求,每个请求包含 15,000 个输入令牌和 5,000 个输出令牌的应用程序,每分钟大约消耗 200,000 个令牌,这可能比每分钟发送 200 个微小提示的应用程序更快地超过 TPM 阈值。

在实践中它看起来像什么

您可能会注意到您的应用程序在正常工作负载下运行顺畅,但在用户粘贴大型文档、上传长篇文本记录或运行批量摘要作业时突然开始失败。这些是令牌吞吐量而非请求频率成为瓶颈的症状。

如何应对

要缓解基于令牌的限流:

  • 通过跟踪 Bedrock 调用的 InputTokenCountOutputTokenCount 指标和日志来监控令牌使用情况。
  • 实施令牌感知的速率限制器,该限制器维护一个滑动 60 秒的已消耗令牌窗口,并且仅在有足够的预算剩余时才发出新请求。
  • 将大型任务分解成更小、更顺序的块,以便将令牌消耗分散到多个分钟,而不是在一瞬间耗尽整个预算。
  • 在适当的情况下使用流式响应;流式传输通常能让您更好地控制何时停止生成,从而避免产生不必要的长输出。

对于持续高容量、令牌密集型的负载,您还应该评估请求更高的 TPM 配额或使用具有更大上下文窗口和更好吞吐量特性的模型。

3. 特定于模型的限流

错误消息:

botocore.errorfactory.ThrottlingException: An error occurred (ThrottlingException) when calling the InvokeModel operation: Model anthropic.claude-haiku-4-5-20251001-v1:0 is currently overloaded. Please try again later.

幕后发生的事情

特定于模型的限流表明特定的模型端点正经历高需求,并且为了控制延迟和稳定性而暂时限制额外流量。在这种情况下,您自己的配额可能不是限制因素;相反,该模型的共享基础设施暂时饱和了。

如何应对

这里最有效的方法之一是设计优雅降级,而不是将其视为硬性失败。

  • 实施模型回退:定义兼容模型的优先级列表(例如,Sonnet → Haiku),如果主模型过载,则自动将流量路由到辅助模型。
  • 将回退与跨区域推理相结合,这样如果一个区域暂时受限,您可以在附近的区域使用相同的模型系列。
  • 在可观测性堆栈中暴露回退行为,以便您可以知道系统何时处于“降级但功能正常”模式,而不是默默地掩盖问题。

实施稳健的重试和速率限制

了解了限流的类型后,下一步是将该知识编码到可重用的客户端组件中。

带抖动的指数退避

这是一个使用带抖动的指数退避的稳健重试实现。此模式对于优雅地处理限流至关重要:

import time
import random
from botocore.exceptions import ClientError

def bedrock_request_with_retry(bedrock_client, operation, **kwargs):
    """安全重试实现,带有清理过的日志记录。"""
    max_retries = 5
    base_delay = 1
    max_delay = 60
    for attempt in range(max_retries):
        try:
            if operation == 'invoke_model':
                return bedrock_client.invoke_model(**kwargs)
            elif operation == 'converse':
                return bedrock_client.converse(**kwargs)
        except ClientError as e:
            # 安全性:记录错误代码,但不记录请求/响应主体
            # 因为它们可能包含敏感的客户数据
            if e.response['Error']['Code'] == 'ThrottlingException':
                if attempt == max_retries - 1:
                    raise
                # 带抖动的指数退避
                delay = min(base_delay * (2 ** attempt), max_delay)
                jitter = random.uniform(0, delay * 0.1)
                time.sleep(delay + jitter)
                continue
            else:
                raise

此模式可避免在限流事件后立即向服务发送请求,并有助于防止许多实例在完全相同的时间重试。

令牌感知的速率限制

对于基于令牌的限流,以下类维护了一个滑动令牌使用窗口,并向调用方提供一个简单的“是/否”答案,说明是否可以发出另一个请求:

import time
from collections import deque

class TokenAwareRateLimiter:
    def __init__(self, tpm_limit):
        self.tpm_limit = tpm_limit
        self.token_usage = deque()

    def can_make_request(self, estimated_tokens):
        now = time.time()
        # 移除早于 1 分钟的令牌
        while self.token_usage and self.token_usage[0][0] < now - 60:
            self.token_usage.popleft()
        current_usage = sum(tokens for _, tokens in self.token_usage)
        return current_usage + estimated_tokens <= self.tpm_limit

    def record_usage(self, tokens_used):
        self.token_usage.append((time.time(), tokens_used))

在实践中,您需要在发送请求前估算令牌,调用 can_make_request,只有在返回 True 时才继续,然后在收到响应后调用 record_usage

理解 503 ServiceUnavailableException

503 ServiceUnavailableException 告诉您 Amazon Bedrock 暂时无法处理您的请求,通常是由于容量压力、网络问题或连接池耗尽。与 429 不同,这与您的配额无关;这与底层服务在该时刻的健康状况或可用性有关。

连接池耗尽

看起来是这样:

botocore.errorfactory.ServiceUnavailableException: An error occurred (ServiceUnavailableException) when calling the ConverseStream operation (reached max retries: 4): Too many connections, please wait before trying again.

在许多实际场景中,此错误并非由 Bedrock 本身引起,而是由客户端的配置方式引起:

  • 默认情况下,boto3 的 HTTP 连接池大小相对较小(例如,10 个连接),这很容易被高并发的工作负载耗尽。
  • 为每次请求创建新的客户端而不是重用单个客户端(每个进程或容器),可能会不必要地增加打开的连接数量。

为了解决这个问题,请共享单个 Bedrock 客户端实例并增加连接池大小:

import boto3
from botocore.config import Config

# 安全最佳实践:切勿硬编码凭据
# boto3 自动使用以下凭据:
# 1. 环境变量 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
# 2. IAM 角色(EC2、Lambda、ECS 推荐)
# 3. AWS 凭据文件 (~/.aws/credentials)
# 4. 服务账户的 IAM 角色(EKS 推荐)

# 为并行执行配置更大的连接池
config = Config(
    max_pool_connections=50, # 从默认的 10 增加
    retries={'max_attempts': 3}
)

bedrock_client = boto3.client('bedrock-runtime', config=config)

此配置允许通过单个、调优良好的客户端进行更多并行请求,而不是达到客户端限制。

临时服务资源问题

看起来是这样:

botocore.errorfactory.ServiceUnavailableException: An error occurred (ServiceUnavailableException) when calling the InvokeModel operation: Service temporarily unavailable, please try again.

在这种情况下,Bedrock 服务正在发出瞬态容量或基础设施问题的信号,通常是在需求高峰期影响按需模型。在这里,您应该将错误视为临时中断,并专注于智能重试和优雅地故障转移:

  • 使用指数退避重试,类似于 429 处理,但参数应针对较慢的恢复进行调整。
  • 考虑使用跨区域推理或不同的服务层级,以便为您最关键的工作负载获得更可预测的容量包络。

高级弹性策略

当您运行任务关键型系统时,简单的重试是不够的;您还希望避免使情况恶化。

断路器模式

断路器模式有助于防止您的应用程序持续调用已失败的服务。相反,在重复失败后,它会迅速切换到“打开”状态,并在冷却期间阻止新请求。

  • CLOSED (关闭) (正常): 请求正常流动。
  • OPEN (打开) (失败): 在重复失败后,新请求立即被拒绝,有助于减轻服务压力并节省客户端资源。
  • HALF_OPEN (半开) (测试): 超时后,允许少量试探性请求;如果成功,电路再次关闭。

这对 Bedrock 为什么重要

当 Bedrock 由于容量问题返回 503 错误时,继续用请求猛击服务只会使情况更糟。断路器模式有助于:

  • 减少挣扎中的服务的负载,帮助它更快恢复
  • 快速失败而不是浪费时间在可能失败的请求上
  • 通过定期测试服务是否再次健康来提供自动恢复
  • 通过快速返回错误而不是超时来改善用户体验

以下代码实现了这一点:

import time
from enum import Enum

class CircuitState(Enum):
    CLOSED = "closed" # 正常操作
    OPEN = "open"     # 失败,拒绝请求
    HALF_OPEN = "half_open" # 测试服务是否恢复

class CircuitBreaker:
    def __init__(self, failure_threshold=5, timeout=60):
        self.failure_threshold = failure_threshold
        self.timeout = timeout
        self.failure_count = 0
        self.last_failure_time = None
        self.state = CircuitState.CLOSED

    def call(self, func, *args, **kwargs):
        if self.state == CircuitState.OPEN:
            if time.time() - self.last_failure_time > self.timeout:
                self.state = CircuitState.HALF_OPEN
            else:
                raise Exception("Circuit breaker is OPEN")
        
        try:
            result = func(*args, **kwargs)
            self.on_success()
            return result
        except Exception as e:
            self.on_failure()
            raise

    def on_success(self):
        self.failure_count = 0
        self.state = CircuitState.CLOSED

    def on_failure(self):
        self.failure_count += 1
        self.last_failure_time = time.time()
        if self.failure_count >= self.failure_threshold:
            self.state = CircuitState.OPEN

# 用法
circuit_breaker = CircuitBreaker()

def make_bedrock_request():
    return circuit_breaker.call(bedrock_client.invoke_model, **request_params)

带有 CRIS 的跨区域故障转移策略

Amazon Bedrock 跨区域推理 (CRIS) 通过提供一种托管方式在区域之间路由流量,从而增加了一层弹性。

  • 全局 CRIS 配置文件:可以将流量发送到 AWS 商业区域,通常提供吞吐量和成本的最佳组合(通常节省约 10%)。
  • 地理 CRIS 配置文件:CRIS 配置文件将流量限制在特定地理区域内(例如,仅限美国、仅限欧盟、仅限 APAC),以帮助满足严格的数据驻留或监管要求。

对于没有数据驻留要求的应用程序,全局 CRIS 可以提高可用性、可靠性和成本效率。

从架构角度来看:

  • 对于不受监管的工作负载,使用全局配置文件可以显著提高可用性并吸收区域性高峰。
  • 对于受监管的工作负载,配置与您的合规边界对齐的地理配置文件,并在治理工件中记录这些决定。

Bedrock 默认使用 TLS 在传输中加密数据,并且默认不存储客户提示或输出;将此与 CloudTrail 日志记录相结合,以实现合规性态势。

429 和 503 错误的监控和可观测性

您无法管理看不见的东西,因此在处理由配额驱动的错误和服务可用性时,强大的监控至关重要。设置全面的 Amazon CloudWatch 监控对于主动错误管理和保持应用程序可靠性至关重要。

注意: CloudWatch 自定义指标、警报和仪表板会根据使用情况产生费用。请参阅CloudWatch 定价了解详情。

必要的 CloudWatch 指标

监控以下 CloudWatch 指标:

  • Invocations:成功的模型调用
  • InvocationClientErrors:4xx 错误,包括限流
  • InvocationServerErrors:5xx 错误,包括服务不可用
  • InvocationThrottles:429 限流错误
  • InvocationLatency:响应时间
  • InputTokenCount/OutputTokenCount:用于 TPM 监控的令牌使用情况

为了获得更好的洞察力,请创建以下仪表板:

  • 将 429 和 503 分开到不同的窗口小部件中,这样您就可以看到高峰是与配额相关的还是与服务相关的。
  • ModelIdRegion 细分指标,以找到出现问题的特定模型或区域。
  • 并排显示当前流量与前几周的比较,以便在问题成为事件之前发现新兴趋势。

关键警报

不要等到用户发现故障时才采取行动。根据以下阈值配置基于 Amazon SNS 通知(Amazon Simple Notification Service)的 CloudWatch 警报:

对于 429 错误:

  • 在 5 分钟窗口内出现大量限流事件。
  • 连续出现非零限流计数,表明持续的压力。
  • 配额利用率高于选定阈值(例如,RPM/TPM 的 80%)。

对于 503 错误:

  • 服务成功率低于您的 SLO(例如,10 分钟内低于 95%)。
  • 与特定区域或模型相关的 503 计数突然激增。
  • 服务可用性(例如,<95% 的成功率)
  • 客户端指标上出现连接池饱和的迹象。

警报配置最佳实践

  • 使用 Amazon Simple Notification Service (Amazon SNS) 主题将警报路由到团队的通信渠道(Slack、PagerDuty、电子邮件)
  • 设置不同的严重性级别:关键(立即采取行动)、警告(尽快调查)、信息(趋势问题)
  • 配置警报操作以在适当情况下触发自动化响应
  • 在详细的警报描述中包含故障排除步骤和运行手册链接
  • 定期测试您的警报以确保通知正常工作
  • 不要在警报消息中包含敏感客户数据

日志分析查询

CloudWatch Logs Insights 查询可帮助您从“我们看到了错误”转变为“我们了解了模式”。示例如下:

查找 429 错误模式:

fields @timestamp, @message
| filter @message like /ThrottlingException/
| stats count() by bin(5m)
| sort @timestamp desc

分析 503 错误与请求量的相关性:

fields @timestamp, @message
| filter @message like /ServiceUnavailableException/
| stats count() as error_count by bin(1m)
| sort @timestamp desc

总结:构建弹性应用

我们在本文中涵盖了很多内容,让我们把它们整合起来。成功处理 Bedrock 错误需要:

  1. 理解根本原因:区分配额限制(429)和容量问题(503)
  2. 实施适当的重试:对每种错误类型使用带有不同参数的指数退避
  3. 为规模化设计:使用连接池、断路器和跨区域故障转移
  4. 主动监控:设置全面的 CloudWatch 监控和警报
  5. 规划增长:请求配额增加并实施回退策略

结论

有效处理 429 ThrottlingException 和 503 ServiceUnavailableException 错误是使用 Amazon Bedrock 运行生产级生成式 AI 工作负载的关键部分。通过结合配额感知的设​​计、智能重试、客户端弹性模式、跨区域策略和强大的可观测性,即使在不可预测的负载下,您也可以保持应用程序的响应能力。

作为下一步,请确定您最关键的 Bedrock 工作负载,启用此处描述的重试和速率限制模式,并构建仪表板和警报,以显示您的真实峰值而不是仅仅显示平均值。随着时间的推移,使用真实流量数据来完善配额、回退模型和区域部署,以便您的 AI 系统在扩展时也能保持强大和可靠。

对于希望加速事件解决的团队,请考虑启用 AWS DevOps Agent——一个人工智能驱动的代理,它通过关联 CloudWatch 指标、日志和警报来调查 Bedrock 错误,就像经验丰富的 DevOps 工程师一样。它会学习您的资源关系,与您的可观测性工具和运行手册配合工作,并通过自动识别根本原因和建议的补救措施,显著减少 429 和 503 错误的平均解决时间 (MTTR)。

了解更多


关于作者

Farzin Bagheri

Farzin Bagheri 是 AWS 的一名首席技术客户经理,wh...




🚀 想要体验更好更全面的AI调用?

欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。

0

评论区