事件驱动架构要点

使用 AWS Lambda 构建无服务器应用

Claudio Canales

Senior DevOps Engineer

回顾:一个 Lambda 心智模型

  • 事件源:触发 Lambda 的对象。
  • 事件负载:描述发生内容的 JSON。
  • 处理器:处理事件的代码。
  • 结果:响应或副作用。
  • 日志:问题排查位置。

Lambda 执行流程

使用 AWS Lambda 构建无服务器应用

事件即消息

  • 事件描述已发生的事。
  • 通常为带元数据的 JSON 消息。
  • 处理器提取字段并执行操作。

门铃类比:事件

使用 AWS Lambda 构建无服务器应用

AWS 常见事件源

  • Amazon S3 在上传时触发事件。
  • Amazon SQS 是托管队列,投递消息。
  • DynamoDB Streams 产生变更日志。
  • 各自产出的 JSON 负载不同。

事件源:S3 vs SQS vs Streams

使用 AWS Lambda 构建无服务器应用

同步 vs 异步调用

  • 同步:调用方等待结果。
  • 异步:调用方仅收到确认;事件稍后处理。

同步 vs 异步类比

使用 AWS Lambda 构建无服务器应用

事件驱动架构要点

  • 事件以 JSON 由 AWS 服务送达。
  • 调用模式决定错误出现位置。
  • 负载各异,需防御式解析与校验。
  • 假设会有重试与重复。

关键要点流程

使用 AWS Lambda 构建无服务器应用

负载即契约

  • 负载是契约:发送方决定其结构。
  • 处理器需知道字段位置。
  • 提取所需、校验、处理并记录日志。

负载契约与解析流程

使用 AWS Lambda 构建无服务器应用

示例负载:SQS 消息事件

带注释的 SQS 事件负载

  • Records 是批次。
  • body 是字符串。
  • messageId 用于追踪和去重。
使用 AWS Lambda 构建无服务器应用

演练:遍历 Records

def lambda_handler(event, context):
    records = event.get("Records", [])
    for record in records:
        body = record.get("body", "")
        print("BODY:", body)
    return {"statusCode": 200}
  • 以安全默认值读取 Records。
  • 遍历每条记录并提取 body。
  • 记录关键信息后返回。

遍历 Records

使用 AWS Lambda 构建无服务器应用

演练:安全解析 JSON body

import json
def lambda_handler(event, context):
    records = event.get("Records") or [{}]
    body = records[0].get("body", "{}")
    payload = json.loads(body)
    oid = payload.get("order_id")
    return json.dumps({"order_id": oid})
  • body 是字符串;用 json.loads 解析。
  • 使用 "{}" 等安全默认值读取。
  • 提取 order_id,用 json.dumps 返回 JSON。

Body 解析流程

使用 AWS Lambda 构建无服务器应用

防御式解析清单

防御式解析清单

  • 学习新事件源时先记录一次事件结构。
  • 对可选字段用 .get() 和默认值。
  • 校验必填字段并返回清晰错误。
  • 处理空批次和缺失键。
使用 AWS Lambda 构建无服务器应用

为重试与重复而设计

  • 许多事件源为至少一次投递。
  • 可能出现重复。
  • 设计幂等处理器,重复处理仍正确。

重试与重复

使用 AWS Lambda 构建无服务器应用

幂等性的实践

  • 选择唯一键,如 messageIdorder_id
  • 将每个已处理键存入 DynamoDB。
  • 检查键是否已存在;存在则跳过。

幂等性决策流程

使用 AWS Lambda 构建无服务器应用

关键要点

  • 事件以 JSON 由 AWS 服务送达。
  • 调用模式决定错误出现位置。
  • 负载各异,需防御式解析与校验。
  • 假设会有重试与重复。

关键要点流程

使用 AWS Lambda 构建无服务器应用

Passons à la pratique !

使用 AWS Lambda 构建无服务器应用

Preparing Video For Download...