无服务计算服务 Lambda
- 引言
- [什么是 AWS Lambda](#什么是 AWS Lambda)
- [SQS 驱动 Lambda](#SQS 驱动 Lambda)
-
- 示例
-
- 场景描述:订单处理系统
- [解决方案:使用 SQS 和 Lambda](#解决方案:使用 SQS 和 Lambda)
- [示例代码:Python Lambda 处理 SQS 消息](#示例代码:Python Lambda 处理 SQS 消息)
- 总结
- [Lambda Application](#Lambda Application)
-
- [Lambda Application 的主要组成部分](#Lambda Application 的主要组成部分)
- [创建和管理 Lambda Application 的方法](#创建和管理 Lambda Application 的方法)
- [使用 Lambda Application 的好处](#使用 Lambda Application 的好处)
- [Lambda Application 示例](#Lambda Application 示例)
引言
前面了解了 《AWS 消息队列服务 SQS》,SQS 通常作为消息的输入来源触发 AWS Lambda 函数进一步处理消息,所以来了解一下 Lambda 函数以及部署。
什么是 AWS Lambda
AWS Lambda 是一种无服务器计算服务,由 Amazon Web Services 提供。它允许开发人员运行代码,而无需管理服务器。
关键特点
以下是 AWS Lambda 的一些关键特点:
-
无服务器架构:Lambda 采用无服务器架构,这意味着开发者不需要管理底层的服务器硬件或操作系统。AWS 自动管理这些基础设施,因此开发者只需专注于编写代码。
-
按需运行:Lambda 函数在被触发时启动,并在执行完成后自动停止。你只需为实际使用的计算时间付费,而不是为持续运行的服务器资源付费。这种按需运行的模式可以节省成本。
-
事件驱动:Lambda 可以响应各种事件触发,包括但不限于:
文件上传:当文件上传到 Amazon S3 存储桶时,可以触发 Lambda 函数进行处理。
数据库变更:当 Amazon DynamoDB 中的数据发生变化时,可以触发 Lambda 进行响应。
消息队列:从 Amazon SQS 队列中接收消息时触发 Lambda 处理。
HTTP 请求:通过 Amazon API Gateway 接收到的 HTTP 请求可以触发 Lambda。
-
自动扩展:Lambda 会根据需求自动扩展,以处理任意数量的并发请求。这意味着无论工作负载是小还是大,Lambda 都能够自动调整并适应需求,不需要人工干预。这对需要处理高流量的应用程序特别有用。
-
支持多种编程语言:Lambda 支持多种编程语言,包括 Python、Node.js、Java、C#、Ruby、Go 等。开发者可以选择他们最熟悉的语言编写代码。
-
与 AWS 生态系统的集成:Lambda 与其他 AWS 服务深度集成,例如 S3、DynamoDB、API Gateway、SNS、SQS 等。这使得开发者能够轻松构建复杂的、基于事件驱动的应用程序。
-
安全性:通过 IAM(身份和访问管理),可以控制 Lambda 函数的访问权限,确保只有授权的资源和用户可以调用函数。
-
简单的部署和版本控制:可以通过 AWS 管理控制台、CLI 或 SDK 轻松部署 Lambda 函数,Lambda 提供了对函数代码的版本控制和别名支持,使得开发者可以轻松管理和部署不同版本的代码。
使用场景
- 实时文件处理:例如,用户上传图片到 S3,Lambda 函数自动被触发来压缩图片或生成缩略图。
- 数据流处理:如通过 Kinesis 或 DynamoDB Streams 进行实时数据处理和分析。
- Web 应用后端:通过 API Gateway 调用 Lambda 处理 HTTP 请求,作为无服务器的 API 后端。
- 自动化任务:例如定时执行的任务,如备份和清理。
AWS Lambda 适用于各种场景,包括实时文件处理、数据转换、API 后端、自动化任务和定时作业等。其无服务器、事件驱动的架构使得开发人员能够更专注于应用程序的功能,而无需担心底层基础设施的管理。
SQS 驱动 Lambda
Amazon SQS(Simple Queue Service)可以驱动 AWS Lambda。这种集成使得开发人员能够创建基于消息队列的事件驱动应用程序。以下是 SQS 如何与 Lambda 集成的关键点:
-
触发 Lambda 函数:你可以配置 Lambda 函数监听一个 SQS 队列。当队列中有新消息时,Lambda 函数将自动触发,并处理这些消息。这种方式常用于处理异步任务或长时间运行的任务。
-
并发性:Lambda 可以自动扩展,以处理 SQS 队列中积压的消息。它根据队列中消息的数量动态分配执行实例,从而确保能够及时处理所有消息。
-
批处理:你可以配置 Lambda 函数从 SQS 队列中一次性读取多条消息。这有助于提高消息处理的效率,减少函数调用的次数。
-
可见性超时和死信队列:在处理 SQS 消息时,可以设置可见性超时(visibility timeout)来防止消息被多次处理。此外,如果消息在重试次数后仍然无法成功处理,可以将其发送到死信队列(Dead Letter Queue),以便后续分析和处理。
-
消息删除:当 Lambda 函数成功处理 SQS 消息后,消息会从队列中自动删除。如果处理失败,消息将被重新排入队列,等待下一次尝试。
-
IAM 权限:为了使 SQS 触发 Lambda,必须为 Lambda 函数配置适当的 IAM 角色和权限。Lambda 需要有权读取 SQS 队列中的消息,并根据需要访问其他 AWS 资源。
示例
下是一个使用 Amazon SQS 驱动 AWS Lambda 的示例场景:
场景描述:订单处理系统
假设你正在构建一个电子商务网站。当客户在网站上下单时,你希望订单能够被异步处理,以确保前端应用程序的响应速度。同时,你希望订单数据能够被记录和处理,以触发后续的操作(如支付处理、库存更新、发货通知等)。
解决方案:使用 SQS 和 Lambda
- 消息队列 (SQS):
创建一个 Amazon SQS 队列,命名为 OrderQueue。这个队列将用于存放客户下单时产生的订单消息。 - 客户下单:
当客户在网站上下单时,订单服务将订单信息(如订单ID、客户ID、产品列表、订单金额等)以消息的形式发送到 OrderQueue 队列。 - Lambda 函数:
- 创建一个 Lambda 函数,命名为 OrderProcessorFunction,其职责是处理订单。该函数的代码可能用 Python、Node.js 或其他支持的语言编写。
- 配置 Lambda 函数以监听 OrderQueue 队列。当 OrderQueue 中有新消息时,Lambda 函数将自动触发。
- Lambda 处理逻辑:
- Lambda 函数读取 OrderQueue 队列中的消息,并解析订单信息。
- 执行以下操作:
验证订单信息的正确性。
调用支付处理服务,完成订单支付。
更新库存系统,减少相应产品的库存数量。
发送通知给客户,确认订单已成功处理。 - 如果 Lambda 函数成功处理了消息,它将自动从 SQS 队列中删除该消息。
- 如果 Lambda 函数失败,消息将重新进入队列,并在稍后重试处理。
- 错误处理和死信队列:
配置 SQS 队列的死信队列(Dead Letter Queue, DLQ)。如果 Lambda 函数在设定的重试次数后仍未能成功处理消息,该消息将被发送到 DLQ 以供后续人工检查和处理。
示例代码:Python Lambda 处理 SQS 消息
下面是一个简单的 Python Lambda 函数代码示例,用于处理来自 SQS 队列的订单消息:
python
import json
import boto3
def lambda_handler(event, context):
# 打印从 SQS 队列收到的事件
print(f"Received event: {json.dumps(event)}")
# 迭代处理每条记录
for record in event['Records']:
# 从 SQS 消息中获取消息体
message_body = json.loads(record['body'])
# 提取订单信息
order_id = message_body['order_id']
customer_id = message_body['customer_id']
order_amount = message_body['order_amount']
# 处理订单逻辑
print(f"Processing order {order_id} for customer {customer_id} with amount {order_amount}")
# 假设我们在此处调用支付服务和更新库存
# 这些服务调用可以使用其他 AWS SDK 服务,如 boto3 访问 DynamoDB、SNS 等
# 如果处理成功,Lambda 会自动删除 SQS 中的消息
# 如果处理失败,抛出异常,消息将重新进入队列
# 可以添加更多业务逻辑处理,异常捕获和错误处理
return {
'statusCode': 200,
'body': json.dumps('Order processed successfully!')
}
总结
这种架构通过 SQS 队列和 Lambda 函数的集成实现了订单的异步处理。SQS 确保订单消息不会丢失,而 Lambda 提供了自动扩展和按需处理的能力。这种设计简化了系统的扩展性和维护,使得构建一个可靠的订单处理系统变得更加容易。
Lambda Application
在 AWS Lambda 中,Application 是指一组相关的 Lambda 函数及其关联的资源、配置和部署逻辑。Lambda Application 可以通过 AWS 服务如 CloudFormation、AWS Serverless Application Model (SAM)、AWS Cloud Development Kit (CDK) 或者通过 AWS 管理控制台来管理。应用程序概念帮助开发者和管理员以模块化和结构化的方式管理无服务器架构,确保不同组件之间的关系和依赖性清晰明确。
Lambda Application 的主要组成部分
-
Lambda 函数:核心的计算单元,执行特定的业务逻辑。一个应用程序可以包含一个或多个 Lambda 函数。
-
事件源:触发 Lambda 函数执行的事件源。例如,S3 对象上传、DynamoDB 表更新、API Gateway 请求、SQS 队列消息等。
-
环境变量:用于在运行时传递配置参数到 Lambda 函数,例如数据库连接字符串、API 密钥等。
-
IAM 角色和权限:定义 Lambda 函数所需的权限,以访问其他 AWS 服务和资源。每个 Lambda 函数通常被分配一个 IAM 角色,明确其可以执行的操作。
-
存储和数据库:与 Lambda 函数交互的持久化存储,如 S3、DynamoDB、RDS、SQS 等。
-
网络配置:如果 Lambda 函数需要访问 VPC 内的资源(如私有子网中的数据库实例),则需要配置 VPC、子网和安全组。
-
监控和日志:通过 Amazon CloudWatch 监控 Lambda 函数的运行状态、执行时间、错误率等。CloudWatch Logs 用于记录详细的执行日志。
-
层 (Layers):Lambda 层用于共享库、依赖项或自定义运行时,多个函数可以共享一个或多个层,减少代码冗余。
-
应用程序包和模板:定义 Lambda Application 所有组成部分及其关系的模板(如 CloudFormation 模板或 SAM 模板)。这些模板描述了整个应用程序的架构,并能自动部署和更新。
创建和管理 Lambda Application 的方法
- AWS 管理控制台
可以通过 AWS 管理控制台中的 Serverless Application Repository 直接搜索和部署现有的应用程序,也可以上传自定义应用程序模板进行部署。 - AWS SAM (Serverless Application Model)
AWS SAM 是一个开源框架,用于构建无服务器应用程序。SAM 模板基于 CloudFormation,扩展了定义 Lambda 函数、API Gateway、DynamoDB 表等无服务器资源的简化语法。通过 SAM CLI,可以打包、测试、部署和管理 Lambda Application。
SAM 模板示例:
yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
MyLambdaFunction:
Type: 'AWS::Serverless::Function'
Properties:
Handler: index.handler
Runtime: python3.9
CodeUri: s3://my-bucket/my-function-code.zip
Environment:
Variables:
TABLE_NAME: my-dynamodb-table
Events:
ApiEvent:
Type: Api
Properties:
Path: /myresource
Method: get
这个模板定义了一个无服务器应用程序,包括一个 Lambda 函数和一个 API Gateway 事件源。
- AWS CDK (Cloud Development Kit)
AWS CDK 提供了一种通过编程语言(如 TypeScript、Python、Java 等)来定义基础设施的方式。开发者可以使用熟悉的编程语言,构建和部署 Lambda Application,同时利用编程语言的特性,如循环、条件判断等。
CDK 示例:
python
from aws_cdk import (
aws_lambda as _lambda,
aws_apigateway as apigateway,
core
)
class MyLambdaApplicationStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# 定义 Lambda 函数
my_lambda = _lambda.Function(
self, 'MyFunction',
runtime=_lambda.Runtime.PYTHON_3_8,
handler='index.handler',
code=_lambda.Code.from_asset('lambda')
)
# 定义 API Gateway 并集成 Lambda 函数
api = apigateway.LambdaRestApi(
self, 'MyApi',
handler=my_lambda
)
- AWS CloudFormation
使用 CloudFormation 直接定义 Lambda Application。CloudFormation 提供了模板化的基础设施管理方式,可以定义和管理包括 Lambda 函数在内的各种 AWS 资源。 - Serverless Framework
Serverless Framework 是一个第三方开源框架,用于构建和部署无服务器应用程序。它支持多种云提供商,并简化了 Lambda 函数、事件源和其他资源的定义。
使用 Lambda Application 的好处
-
模块化:将相关的 Lambda 函数和资源打包成一个应用程序,便于管理和部署。
-
自动化:通过模板定义,应用程序的创建、更新和删除可以完全自动化,减少手动配置错误。
-
可重复性:使用相同的模板,可以在不同环境中一致地部署应用程序,如开发、测试和生产环境。
-
版本控制:应用程序模板可以放入版本控制系统(如 Git),方便跟踪和管理变化。
-
集成:Lambda Application 可以与其他 AWS 服务无缝集成,实现复杂的业务逻辑,如事件驱动架构、实时数据处理、API 管理等。
通过 Lambda Application 的概念和工具,开发者能够更加高效、结构化地构建、部署和管理无服务器架构,充分利用 AWS 提供的计算、存储和网络资源。
Lambda Application 示例
我们将创建一个简单的订单处理系统,当新订单被添加到 SQS 队列中时,Lambda 函数会被触发来处理这些订单。
场景描述
- 有一个 SQS 队列用于接收订单消息。
- 当新订单消息进入 SQS 队列时,触发 Lambda 函数。
- Lambda 函数从队列中读取订单消息,进行处理(例如,解析订单内容并打印日志)。
系统架构
-
SQS 队列:接收订单消息。每个订单作为一个 JSON 对象发送到队列中。
-
Lambda 函数(OrderProcessorFunction):处理订单消息。Lambda 函数被配置为从 SQS 队列中读取消息并执行相应的业务逻辑。
-
IAM 角色:为 Lambda 函数提供必要的权限,以读取 SQS 队列中的消息。
-
CloudFormation 模板:使用模板定义所有的 AWS 资源,包括 SQS 队列、Lambda 函数和 IAM 角色。
CloudFormation 模板定义
以下是 CloudFormation 模板,定义了 SQS 队列、Lambda 函数、IAM 角色及其之间的关系。
yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# 定义 SQS 队列
OrderQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: OrderQueue
# 定义 IAM 角色,用于 Lambda 函数访问 SQS
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: SqsLambdaPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- sqs:ReceiveMessage
- sqs:DeleteMessage
- sqs:GetQueueAttributes
Resource: !GetAtt OrderQueue.Arn
# 定义 Lambda 函数
OrderProcessorFunction:
Type: AWS::Lambda::Function
Properties:
Handler: order_processor.lambda_handler
Runtime: python3.9
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
for record in event['Records']:
# 获取 SQS 消息主体
payload = record['body']
logger.info(f'Received order: {payload}')
# 处理订单逻辑
order = json.loads(payload)
process_order(order)
return {
'statusCode': 200,
'body': json.dumps('Order processed successfully')
}
def process_order(order):
# 简单地打印订单内容(在实际应用中,可能会将订单保存到数据库或触发其他服务)
logger.info(f'Processing order for customer: {order["customer_name"]}, total amount: {order["total_amount"]}')
# 配置 Lambda 函数触发器,以便从 SQS 队列读取消息
LambdaSQSTrigger:
Type: AWS::Lambda::EventSourceMapping
Properties:
BatchSize: 10
EventSourceArn: !GetAtt OrderQueue.Arn
FunctionName: !Ref OrderProcessorFunction
模板中的关键部分
- SQS 队列(OrderQueue):
创建一个名为 OrderQueue 的 SQS 队列,用于接收订单消息。 - IAM 角色(LambdaExecutionRole):
定义一个 IAM 角色,为 Lambda 函数提供访问 SQS 队列的权限。该角色允许 Lambda 函数从队列接收消息、删除消息,以及获取队列属性。 - Lambda 函数(OrderProcessorFunction):
使用 Python 3.9 运行时。函数的代码嵌入在 CloudFormation 模板中,负责从 SQS 读取消息并处理订单。实际应用中,Lambda 代码通常会托管在 S3 或代码库中。 - Lambda 触发器(LambdaSQSTrigger):
定义一个事件源映射,将 SQS 队列与 Lambda 函数绑定。这样,当队列中有消息时,Lambda 函数就会被触发。BatchSize 指定了每次最多处理的消息数量。
部署 CloudFormation 模板
- 准备模板文件:将上面的 CloudFormation 模板保存为 order-processing-template.yaml 文件。
- 部署模板:使用 AWS CLI 部署 CloudFormation 模板。
bash
aws cloudformation create-stack --stack-name OrderProcessingApp --template-body file://order-processing-template.yaml --capabilities CAPABILITY_NAMED_IAM
--capabilities CAPABILITY_NAMED_IAM 参数用于授权 CloudFormation 创建 IAM 角色。
- 测试系统:
部署完成后,CloudFormation 会创建 SQS 队列和 Lambda 函数。
可以向 SQS 队列发送测试消息来验证 Lambda 函数是否正常工作。例如,使用 AWS CLI 或其他 SQS 客户端发送一条消息:
bash
aws sqs send-message --queue-url https://sqs.<region>.amazonaws.com/<account-id>/OrderQueue --message-body '{"customer_name": "John Doe", "total_amount": 100}'
- 验证结果:
检查 CloudWatch Logs,确认 Lambda 函数已处理订单消息并输出日志:
bash
INFO: Received order: {"customer_name": "John Doe", "total_amount": 100}
INFO: Processing order for customer: John Doe, total amount: 100
总结
这个示例展示了如何使用 AWS CloudFormation 配置 SQS 触发 Lambda 函数。通过 CloudFormation 模板,我们可以轻松定义 SQS 队列、Lambda 函数及其 IAM 权限,并且使其自动化部署和管理。这样的架构非常适合用于处理异步任务、事件驱动的工作流等场景,具有高度的可扩展性和灵活性。