AWS Lambda 无服务器实战:从0搭建API完整教程(2026最新版)
Meta Description: AWS Lambda 无服务器架构实战教程:从创建第一个函数到 API Gateway 集成,涵盖 Node.
- 前言
- AWS Lambda 核心概念
- 步骤一:创建你的第一个 Lambda 函数
- 步骤二:用 API Gateway 暴露 HTTP 接口
- 步骤三:添加 POST 方法处理请求体
- 步骤四:连接 DynamoDB 实现数据持久化
- AWS Lambda 定价详解
- Lambda vs EC2:选型对比
Meta Description: AWS Lambda 无服务器架构实战教程:从创建第一个函数到 API Gateway 集成,涵盖 Node.js/Python 代码示例、价格对比、冷启动优化与常见问题解答。
关键词:AWS Lambda、无服务器架构、API Gateway、Serverless、Lambda函数、冷启动优化、云函数
前言
如果你还在为管理 EC2 实例的补丁、扩容、安全组而头疼,那么 AWS Lambda 可能会让你眼前一亮。Lambda 是 AWS 最核心的无服务器计算服务——你只需上传代码,AWS 负责所有的服务器管理、自动扩容和按毫秒计费。不需要预置实例、不需要担心流量峰值,代码被调用时才产生费用。
本教程将带你从零开始,用 AWS Lambda + API Gateway 搭建一个完整的 REST API,并深入讲解定价模型、性能优化和常见陷阱。
AWS Lambda 核心概念
在动手之前,先理解几个关键概念:
| 概念 | 说明 |
|---|---|
| 函数(Function) | 你的代码单元,由事件触发执行 |
| 事件源(Event Source) | 触发函数的东西:API Gateway、S3 上传、DynamoDB 变更、CloudWatch 定时等 |
| 运行时(Runtime) | 支持的语言:Node.js、Python、Java、Go、.NET、Ruby,以及自定义运行时 |
| 内存/CPU | 128MB ~ 10,240MB,CPU 随内存线性增长 |
| 超时时间 | 最长 15 分钟(900 秒) |
| 临时存储 | /tmp 目录,512MB ~ 10GB(可配置) |
| 并发限制 | 默认 1,000 并发/区域,可申请提升 |
步骤一:创建你的第一个 Lambda 函数
登录 AWS 控制台,进入 Lambda 服务页面,点击"创建函数"。
选择"从头开始创建",填入以下信息:
- 函数名称:
hello-world-api - 运行时:Python 3.12
- 架构:x86_64(如需更低成本可选 arm64,Graviton 处理器)
- 权限:选择"创建具有基本 Lambda 权限的新角色"
点击创建后,你会看到内嵌的代码编辑器。将默认代码替换为:
import json
def lambda_handler(event, context):
// 从 API Gateway 传入的请求中获取参数
http_method = event.get('httpMethod', 'GET')
query_params = event.get('queryStringParameters', {}) or {}
name = query_params.get('name', '世界')
// 构造响应
response = {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'message': f'你好,{name}!',
'method': http_method,
'timestamp': context.get_remaining_time_in_millis()
}, ensure_ascii=False)
}
return response
点击 Deploy 保存代码。
步骤二:用 API Gateway 暴露 HTTP 接口
Lambda 函数本身无法从公网直接访问——你需要 API Gateway 作为前端。
- 进入 API Gateway 控制台,选择"REST API"(不要选 HTTP API,REST API 功能更全)
- 点击"构建",选择"新建 API":
- API 名称:
hello-world-api - 端点类型:区域
- 创建资源
/hello,然后创建 GET 方法 - 集成类型选择"Lambda 函数",勾选"使用 Lambda 代理集成"
- 选择刚才创建的
hello-world-api函数 - 点击"部署 API",新建一个阶段(stage)命名为
prod
部署完成后,你会得到一个调用 URL,类似:
https://abc123xyz.execute-api.ap-southeast-1.amazonaws.com/prod/hello
用 curl 测试:
curl "https://abc123xyz.execute-api.ap-southeast-1.amazonaws.com/prod/hello?name=AWS"
// 返回:{"message": "你好,AWS!", "method": "GET", "timestamp": 28500}
步骤三:添加 POST 方法处理请求体
在 /hello 资源下再创建一个 POST 方法,同样指向 hello-world-api 函数。修改 Lambda 代码以支持两种方法:
import json
def lambda_handler(event, context):
http_method = event.get('httpMethod', 'GET')
if http_method == 'POST':
body = json.loads(event.get('body', '{}'))
data = body.get('data', {})
return {
'statusCode': 201,
'headers': {
'Content-Type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'message': '数据接收成功',
'received': data
}, ensure_ascii=False)
}
// GET 请求
query_params = event.get('queryStringParameters', {}) or {}
name = query_params.get('name', '世界')
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({'message': f'你好,{name}!'}, ensure_ascii=False)
}
测试 POST:
curl -X POST "https://abc123xyz.execute-api.ap-southeast-1.amazonaws.com/prod/hello" \
-H "Content-Type: application/json" \
-d '{"data": {"action": "create", "id": 12345}}'
步骤四:连接 DynamoDB 实现数据持久化
真正的 API 需要读写数据库。以下是 Lambda + DynamoDB 的完整示例:
import json
import boto3
import os
from datetime import datetime
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ.get('TABLE_NAME', 'tasks'))
def lambda_handler(event, context):
http_method = event.get('httpMethod', 'GET')
path_params = event.get('pathParameters', {}) or {}
if http_method == 'GET':
if path_params.get('taskId'):
// 获取单个任务
resp = table.get_item(Key={'taskId': path_params['taskId']})
return api_response(200, resp.get('Item', {}))
else:
// 列出所有任务
resp = table.scan(Limit=50)
return api_response(200, resp.get('Items', []))
elif http_method == 'POST':
body = json.loads(event.get('body', '{}'))
item = {
'taskId': body.get('taskId', str(int(datetime.now().timestamp()))),
'title': body.get('title', ''),
'status': body.get('status', 'pending'),
'createdAt': datetime.now().isoformat()
}
table.put_item(Item=item)
return api_response(201, item)
elif http_method == 'DELETE':
table.delete_item(Key={'taskId': path_params['taskId']})
return api_response(200, {'deleted': True})
return api_response(405, {'error': 'Method not allowed'})
def api_response(status_code, body):
return {
'statusCode': status_code,
'headers': {
'Content-Type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps(body, ensure_ascii=False)
}
别忘了给 Lambda 执行角色附加 DynamoDB 权限策略 AmazonDynamoDBFullAccess(生产环境应最小化权限)。
AWS Lambda 定价详解
Lambda 按两个维度计费:请求次数 + 执行时长。
请求费用
| 项目 | 费用 |
|---|---|
| 每 100 万次请求 | $0.20 |
| 每月前 100 万次请求 | 免费(永久免费套餐) |
计算时长费用
按 GB-秒计费,即分配的内存 × 执行时间:
| 架构 | 每 GB-秒价格 |
|---|---|
| x86_64 | $0.0000166667(即每毫秒 $0.0000000167) |
| Arm (Graviton) | $0.0000133334(便宜 20%) |
实际场景费用估算
| 场景 | 请求量/月 | 内存 | 平均耗时 | 月费用 |
|---|---|---|---|---|
| 个人博客 API | 10 万次 | 256MB | 100ms | $0.00(全免) |
| 小型 SaaS | 500 万次 | 512MB | 200ms | ~$2.56 |
| 中型电商 | 5,000 万次 | 1GB | 300ms | ~$35.00 |
| 高频交易系统 | 1 亿次 | 2GB | 50ms | ~$30.00 |
Lambda vs EC2:选型对比
很多用户纠结于"该用 Lambda 还是 EC2",这里做一个全面对比:
| 维度 | AWS Lambda | EC2 |
|---|---|---|
| 管理负担 | 零运维,AWS 全托管 | 需要管理 OS、补丁、扩容 |
| 计费粒度 | 按毫秒,不调用不收费 | 按小时/秒,运行即计费 |
| 启动时间 | 冷启动 100ms~2s | 实例始终运行,无延迟 |
| 最长执行 | 15 分钟 | 无限制 |
| 最大内存 | 10GB | 最高 24TB |
| 临时存储 | 最大 10GB (/tmp) | 无限制(EBS) |
| 成本(低流量) | 极低,甚至免费 | 最低约 $3.5/月(t4g.nano) |
| 成本(高流量) | 线性增长 | 预留实例可极大降低成本 |
| 适用场景 | 事件驱动、API、定时任务 | 持续运行、数据库、游戏服务器 |
什么时候选 Lambda?
- ✅ 流量有波峰波谷(夜间几乎为零)
- ✅ API 后端,调用不频繁
- ✅ 定时任务(CloudWatch Events 触发)
- ✅ 文件处理(S3 上传触发缩图/转码)
- ✅ 每次执行 < 15 分钟
什么时候选 EC2/Lightsail?
- ✅ 需要持续运行的服务(WebSocket、游戏服务器)
- ✅ 执行时间 > 15 分钟的计算任务
- ✅ 需要固定 IP 或特定网络配置
- ✅ 高并发场景下预留实例更省钱
Lambda 冷启动优化实战
"冷启动"是 Lambda 最大的性能挑战——当函数一段时间未被调用后,AWS 需要初始化一个新的执行环境,这个过程可能耗时 100ms 到 2 秒。
冷启动耗时对比
| 运行时 | 冷启动(256MB) | 热启动 |
|---|---|---|
| Python 3.12 | ~350ms | ~1ms |
| Node.js 20 | ~250ms | ~1ms |
| Java 21 | ~1.2s | ~2ms |
| Go | ~200ms | ~1ms |
| .NET 8 | ~1.5s | ~2ms |
优化策略
- 选择轻量运行时:Python 和 Node.js 冷启动最快,Java 和 .NET 最慢
- 减少依赖包大小:只导入需要的模块,用 Lambda Layer 共享公共依赖
- 提高内存配置:内存越大,CPU 越强,初始化越快(1769MB 以上有专用 vCPU)
- 使用 Provisioned Concurrency(预置并发):保持指定数量的执行环境始终热启动,但需要额外付费
- 避免 VPC:不需要访问 VPC 内资源的函数不要配 VPC——VPC 冷启动额外增加 2~3 秒(需要创建 ENI)
- Arm 架构:Graviton 处理器冷启动比 x86 快约 15%
Provisioned Concurrency 价格
| 架构 | 每 GB-秒 Provisioned | 每 GB-秒 请求 |
|---|---|---|
| x86 | $0.000004167 | $0.000009722 |
| Arm | $0.000003334 | $0.000007778 |
步骤五:用 CloudWatch 监控和调试
每个 Lambda 函数自动集成 CloudWatch Logs。你可以在代码中添加:
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
logger.info(f"收到请求: {json.dumps(event)}")
// ... 业务逻辑 ...
logger.info(f"执行完成, 剩余时间: {context.get_remaining_time_in_millis()}ms")
在 CloudWatch Logs 中搜索日志组 /aws/lambda/hello-world-api 即可查看。
此外,Lambda 控制台内置了 CloudWatch 监控指标:
- Invocations(调用次数)
- Duration(执行时长)
- Error count / Success rate(错误率)
- Throttles(限流次数)
- IteratorAge(流处理延迟)
常见陷阱与最佳实践
陷阱一:忘记设置超时时间
Lambda 默认超时仅 3 秒。如果你的函数需要访问外部 API 或数据库(通常 500ms~2s),一定要在配置中将超时调至 10~30 秒。
陷阱二:在函数外部初始化数据库连接
// ❌ 错误:每次请求都创建新连接,极慢
def lambda_handler(event, context):
conn = pymysql.connect(...) # 冷启动时耗时 200ms+
...
// ✅ 正确:在全局作用域初始化,跨请求复用(热启动时直接使用)
conn = None
def get_conn():
global conn
if conn is None or not conn.open:
conn = pymysql.connect(...)
return conn
def lambda_handler(event, context):
conn = get_conn() # 热启动时几微秒
...
陷阱三:递归调用导致账单爆炸
Lambda 函数内部调用自己的模式(例如 S3 事件 → Lambda → S3 写入 → 又触发 Lambda)会造成无限循环。务必确保事件源和触发条件不会形成闭环。
陷阱四:忽略并发限制导致丢请求
默认 1,000 并发,超出后请求被限流(429 错误)。如果流量突增:
- 申请提高并发配额
- 使用 SQS 作为缓冲(API Gateway → SQS → Lambda)
- 配置预留并发(Reserved Concurrency)保护下游资源
AWS Lambda 与其他云厂商 Serverless 对比
| 功能 | AWS Lambda | 阿里云函数计算 FC | 腾讯云 SCF |
|---|---|---|---|
| 免费额度 | 100万次/月 + 40万GB秒/月 | 100万次/月 | 100万次/月 |
| 支持语言 | 7种 + 自定义运行时 | 6种 + 自定义运行时 | 5种 + 自定义运行时 |
| 最大内存 | 10GB | 16GB | 3GB |
| 最长超时 | 15分钟 | 24小时 | 15分钟 |
| VPC 支持 | ✅(冷启动+2s) | ✅ | ✅ |
| GPU 支持 | ❌ | ✅(弹性GPU) | ❌ |
| 全球区域 | 30+ | 20+ | 10+ |
总结
AWS Lambda 是现代云架构中不可或缺的一环。它让开发者从服务器管理中解放出来,专注于业务代码本身。对于 API 后端、数据处理、定时任务等场景,Lambda + API Gateway + DynamoDB 的组合可以以极低的成本(甚至免费)构建完整应用。
核心要点回顾:
- 按毫秒计费,不调用不花钱——比 EC2 更适合流量不均的场景
- 冷启动是最大的性能挑战,Python/Node.js 选型 + 合理内存配置可以控制在 300ms 以内
- 生产环境务必配置超时、并发限制和监控告警
- 免费套餐足够覆盖个人项目和中小型 API
🚀 需要 AWS 国际版账号?通过 3.chengzicloud.cloud 获取最新注册教程与专属优惠,助你轻松上云。
本文由 3.chengzicloud.cloud 提供,点击访问首页了解更多
常见问题(FAQ)
1: Lambda 免费套餐真的永久免费吗?
是的,AWS Lambda 永久免费套餐包括每月 100 万次请求和 40 万 GB-秒的计算时长。对于个人项目、博客 API、学习测试等低流量场景,基本不需要花钱。但要注意:如果使用了 API Gateway、DynamoDB 等其他服务,那些服务可能产生费用。
2: 冷启动到底有多慢?能彻底消除吗?
Python/Node.js 通常 200~500ms,Java 可能 1~2 秒。如果使用 Provisioned Concurrency(预置并发),可以彻底消除冷启动,但需要额外付费。大多数 API 场景下,偶尔的冷启动是可接受的——用户几乎感知不到 300ms 的额外延迟。
3: Lambda 能用环境变量吗?
可以,而且推荐的实践是通过环境变量传递配置(数据库连接串、API 密钥等),避免硬编码。敏感信息建议用 AWS Secrets Manager 或 Parameter Store(在代码中按需获取并缓存)。
4: Lambda 和 Fargate 有什么区别?
Lambda 是无服务器函数(事件驱动、按请求计费、最长 15 分钟),Fargate 是无服务器容器(持续运行、支持任意语言、无时间限制)。简单选择:需要快速响应的事件驱动任务选 Lambda,需要长时间运行的容器化服务选 Fargate。
5: 如何防止 Lambda 被 DDoS 攻击产生天价账单?
三招:① API Gateway 设置限流(rate limiting);② Lambda 设置预留并发上限;③ 启用 AWS WAF 防护 API Gateway。这样即使遭受攻击,调用次数和并发都被硬性限制,不会产生意外费用。