从 EC2 迁移到 Lambda + Bedrock:一次 Serverless AI 架构实践的完整复盘
前言
在做技术选型的时候,"用不用 Serverless" 这个问题经常被讨论。这篇文章不谈理论,记录一次真实的迁移过程——把一个跑在 EC2 上的 AI 问答服务,迁移到 Lambda + Bedrock 的 Serverless 架构。重点分析迁移动机、技术实现、踩坑过程和最终效果。
迁移动机
原来的架构是经典的 EC2 + FastAPI:
- EC2 t3.medium 跑 Python FastAPI
- 接受用户问题,调用 Bedrock API 返回回答
- 7×24 运行,主要工作时间(8:00-18:00)有请求
问题在于:这台服务器大部分时间是空闲的。实际计算表明,每天真正在处理请求的时间不超过 10 分钟。剩下的 23 小时 50 分钟都在空转。
按照亚马逊云科技 Lambda 的计费模型——只在代码运行时才收费——这个场景非常适合做 Serverless 改造。
新架构
客户端 → API Gateway (HTTP API) → Lambda → Bedrock (Claude 3.5 Sonnet) → 客户端
去掉了 EC2 和 FastAPI,Lambda 直接承接原来的 API 逻辑。
核心函数
import json
import boto3
bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
def lambda_handler(event, context):
body = json.loads(event.get('body', '{}'))
question = body.get('question', '')
if not question:
return {'statusCode': 400, 'body': json.dumps({'error': '缺少问题参数'})}
response = bedrock.invoke_model(
modelId='anthropic.claude-3-5-sonnet-20241022-v2:0',
contentType='application/json',
accept='application/json',
body=json.dumps({
'anthropic_version': 'bedrock-2023-05-31',
'max_tokens': 2048,
'messages': [{'role': 'user', 'content': question}]
})
)
result = json.loads(response['body'].read())
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({'answer': result['content'][0]['text']})
}
比 FastAPI 版本少了一半代码。不需要 uvicorn、不需要 requirements.txt(boto3 是 Lambda 内置的)、不需要 Dockerfile。
迁移中的关键问题
问题一:IAM 权限配置
这个坑了不少人。Bedrock foundation model 的 ARN 有个特殊格式:
arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-*
中间 :: 是对的——账号 ID 字段为空。跟大多数亚马逊云科技服务的 ARN 格式不同。
问题二:超时配置
Lambda 默认超时 3 秒,而 Bedrock Claude 模型的响应时间在 5-15 秒之间。迁移后第一次测试 100% 超时。
需要调整到至少 30 秒,给模型足够的响应时间。
问题三:冷启动延迟
EC2 方案是常驻的,响应延迟稳定。Lambda 冷启动后,首次请求延迟会增加 2-5 秒。
对于低频场景可以接受。如果对延迟敏感,可以配置预置并发(Provisioned Concurrency),代价是固定费用——但仍然比 EC2 便宜。
问题四:Bedrock 区域限制
Lambda 部署在 ap-northeast-1(东京),但 Bedrock 的 Claude 模型当时只在 us-east-1 和 us-west-2 可用。需要跨区域调用,增加约 50-100ms 网络延迟。在 AI 应用场景下(本身就要等几秒),这个额外延迟可以忽略。
迁移前后对比
| 指标 | EC2 方案 | Lambda 方案 |
|---|---|---|
| 月成本(不含模型费) | ~$30 | ~$0.20 |
| 部署复杂度 | Dockerfile + systemd + nginx | 一个 Python 文件 |
| 运维工作 | 系统更新、监控、备份 | 基本为零 |
| 冷启动延迟 | 无 | 2-5 秒(可优化) |
| 自动扩缩容 | 需要手动配置 ASG | 内置 |
| 最大并发 | 受实例规格限制 | 默认 1000 并发 |
哪些场景不适合迁移
实事求是地说,不是所有场景都适合 Serverless:
- 高并发持久连接:WebSocket 聊天场景,Lambda 的执行时间限制(15 分钟)和连接管理不方便
- 自定义模型推理:需要加载几 GB 的模型权重,Lambda 的
/tmp只有 512MB-10GB - 稳定高负载:如果 QPS 持续很高(每秒几百次),EC2 预留实例可能更划算
总结
这次迁移的核心收益是成本降了 99%,从每月 $30 降到 $0.20。代价是冷启动延迟和一些架构限制。
对于低频、事件驱动的 AI 应用场景,Lambda + Bedrock 的组合非常高效。不需要管理服务器,不需要操心扩缩容,按调用付费。
以上所有代码和配置基于亚马逊云科技 Lambda Python 3.12 运行时和 Bedrock Claude 3.5 Sonnet 模型验证通过。

浙公网安备 33010602011771号