使用 FastAPI 构建弹性 AI 架构

发布: (2026年2月4日 GMT+8 19:01)
11 分钟阅读
原文: Dev.to

Source: Dev.to

构建弹性 AI 架构的 FastAPI 封面图片

随着 AI 驱动的应用从实验性原型转向关键任务的生产服务,弹性、可扩展性和容错性变得至关重要。现代 AI 系统——尤其是使用 Azure OpenAI 等大型语言模型(LLM)的系统——必须能够应对网络不稳定、配额限制、区域性故障以及动态的使用模式。

本文提供了一套实用指南,帮助你构建弹性的 AI 服务,涉及以下技术:

  • Python FastAPI 微服务
  • Redis 缓存(通过 AWS ElastiCache)
  • Azure OpenAI Provisioned Throughput Units (PTUs)
  • 高级重试逻辑与灾难恢复策略
  • 通过 AWS Secrets Manager 实现安全的配置管理

为什么在 AI 中弹性是不可协商的

AI 服务,尤其是依赖 LLM API 的服务,面临独特的运营挑战:

挑战影响
速率和配额限制API 提供商施加令牌/请求上限;需要智能处理。
瞬时故障网络中断或服务器错误导致间歇性请求失败。
延迟敏感性用户期望近实时响应;性能至关重要。
区域性故障云服务中断可能影响整个地理区域。

Source:

架构概览

一个异步的 FastAPI 微服务是系统的核心。它与 Azure OpenAI PTU 进行 LLM 推理通信,并使用 Redis 实现低延迟响应缓存。敏感凭证和重试配置存储在 AWS Secrets Manager 中,而多区域故障转移则通过 Route 53 DNS 地理路由和健康检查来编排。

这种分层设计同时解决了性能和容错问题:

  • Redis 减少不必要的 API 调用。
  • 重试逻辑 平滑间歇性的网络故障。
  • 多区域部署 确保在大规模故障期间的连续性。

架构图

          _Architecture of an Enterprise-Grade AI_

我们的架构利用关键组件来确保稳健性:

组件图

Source:

深入了解关键弹性使能因素

使用 FastAPI 为 API 加速

FastAPI 是一个异步的 Python Web 框架,提供高并发和快速响应时间——非常适合 AI 后端微服务。

from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

这个简单的健康检查端点是实现高可用路由策略(例如 AWS Route 53 提供的策略)的关键。

配置层:安全且动态的设置

在代码中嵌入凭证或重试参数会带来安全风险和运维僵化。相反,这种架构在启动时从 AWS Secrets Manager 拉取密钥(如 API 密钥、重试策略),并使用 Python 的 @lru_cache 装饰器将其缓存到内存中。

import boto3
import json
from functools import lru_cache

@lru_cache()
def get_secrets(secret_name: str = "prod/llm-config") -> dict:
    client = boto3.client("secretsmanager")
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response["SecretString"])

动态的密钥获取使得可以在不重新部署服务的情况下更新设置——例如重试策略或 API 密钥。

弹性层:智能重试与故障转移

分布式系统中的故障是不可避免的,目标是优雅地处理它们。我们的弹性策略基于三个核心概念:

1. 多 PTU 端点的冗余

来自 Azure OpenAI 的 Provisioned Throughput Unit (PTU) 能保证处理容量,但单个 PTU 可能成为瓶颈或在区域性故障时失效。为此,我们在不同的 Azure 区域(例如 East US、West Europe)部署多个 PTU。应用将这些 PTU 端点视为一个池;如果对某个端点的请求失败,系统会自动切换到下一个端点进行重试,从而实现负载均衡和区域冗余。

2. 带抖动的指数退避

当出现瞬时错误时,立即重试可能加剧问题(即“重试风暴”)。我们实现 带抖动的指数退避

import random
import asyncio

async def retry_with_backoff(
    coro,
    max_attempts: int = 5,
    base_delay: float = 0.5,
    jitter: float = 0.1,
):
    for attempt in range(1, max_attempts + 1):
        try:
            return await coro()
        except Exception:
            if attempt == max_attempts:
                raise
            delay = base_delay * (2 ** (attempt - 1))
            delay += random.uniform(-jitter, jitter) * delay
            await asyncio.sleep(delay)
  • 指数增长base_delay * 2^(attempt‑1))让重试间隔逐渐拉大。
  • 抖动± jitter * delay)防止大量客户端同步重试。

3. 熔断器模式

为避免在长时间故障期间对下游服务造成压垮,我们使用 熔断器。当错误阈值超过配置值时,熔断器打开,在冷却期间短路后续调用。

from pybreaker import CircuitBreaker

llm_breaker = CircuitBreaker(
    fail_max=5,        # 最大连续失败次数
    reset_timeout=30, # 重新尝试前的冷却秒数
)

@llm_breaker
async def call_llm(payload):
    # 调用 Azure OpenAI PTU 端点
    ...

当熔断器打开时,服务可以返回缓存的响应或优雅降级的提示信息,从而保持用户体验。

灾难恢复与可观测性

  • Multi‑region deployment: 在至少两个 Azure 区域部署 FastAPI 实例和 Redis 集群。使用 Route 53 健康检查将 DNS 故障转移到健康的区域。
  • Backup & Restore: 为 Redis(ElastiCache)启用自动快照,并导出 Secrets Manager 的版本。
  • Monitoring: 利用 Prometheus + Grafana 监控延迟、错误率和重试指标。导出自定义指标(例如,断路器状态)以帮助进行根因分析。
  • Logging: 使用 AWS CloudWatchELK 堆栈集中日志;包含关联 ID 以在服务之间追踪请求。

综合示例 – 请求流程

  1. Client → FastAPI: 请求命中最近的 FastAPI 实例(由 DNS 决定)。
  2. FastAPI → Redis: 检查缓存中是否有最近的响应。
    • Cache hit → 返回缓存结果。
    • Cache miss → 继续执行第 3 步。
  3. FastAPI → Azure PTU Pool: 使用 retry_with_backoff + circuit breaker 调用可用的 PTU 接口。
  4. Response → Redis: 将新结果存入缓存并设置 TTL(例如 5 分钟)。
  5. FastAPI → Client: 返回响应。

可观测性

你无法修复看不见的问题。对每次尝试使用结构化日志记录以下内容:

  • 使用的端点
  • 失败原因
  • 应用的延迟
  • 最终结果

这些日志会输入监控仪表盘(例如 Grafana),并在失败率或令牌使用量超过预设阈值时触发自动警报。

可伸缩层:使用 Kubernetes 的弹性伸缩

为应对需求波动,我们在 Kubernetes 上部署 FastAPI 服务,并使用 水平 Pod 自动伸缩器 (HPA)。HPA 会根据 CPU 利用率等指标自动增加或减少服务 Pod 的数量。

示例 HPA 策略

设置
目标 CPU 利用率60 %
最小副本数2
最大副本数20

这确保在流量激增或区域故障切换事件期间,我们的服务能够即时扩容以满足增加的负载,保持性能而无需人工干预。

关键要点

构建企业级 AI 服务意味着从一开始就要把弹性放在首位。这不是事后考虑的,而是核心的架构需求。

  • 为故障而设计 – 假设网络、API,甚至整个云区域都会出现故障。构建机制以优雅地处理这些事件。
  • 解耦并集中配置 – 使用 AWS Secrets Manager 等服务在外部管理设置。这可以提升安全性和运营敏捷性。
  • 实现智能重试 – 结合多个冗余端点、指数退避和抖动,以克服瞬时问题,同时避免对依赖服务造成过大压力。
  • 自动化扩展和故障转移 – 利用 Kubernetes HPA 和 AWS Route 53 等工具,创建能够自我修复和自适应的系统,无需人工干预。

通过结合这些实践,您可以构建出不仅功能强大的 AI 服务,还能提供用户期望的稳定性和可靠性。

结论

大规模运行的 AI 系统必须在设计上具备弹性。通过结合异步 API、安全配置、智能重试、跨区域故障转移和自动扩缩容,您可以提供在不利条件下仍保持稳定、高性能和透明的 AI 服务。

关键洞见: 弹性不是一种优化,而是生产 AI 系统的基本需求。


Resilience Diagram

Back to Blog

相关文章

阅读更多 »

当 AI 给你一巴掌

当 AI 给你当头一棒:在 Adama 中调试 Claude 生成的代码。你是否曾让 AI “vibe‑code” 一个复杂功能,却花了数小时调试细微的 bug……