教程:使用 Lambda 函数访问 Amazon RDS 数据库 - Amazon Relational Database Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

教程:使用 Lambda 函数访问 Amazon RDS 数据库

在本教程中,您使用 Lambda 函数通过 RDS 代理将数据写入 Amazon Relational Database Service(Amazon RDS)数据库。您的 Lambda 函数在 Amazon Simple Queue Service(Amazon SQS)队列中读取记录,每当添加消息时,都将新的项目写入您数据库的表中。在此示例中,您使用 Amazon Web Services Management Console 手动向队列添加消息。下图显示了您用于完成教程的 Amazon 资源。


      Amazon Web Services Management Console的实例连接到 Amazon SQS 标准队列,该队列连接到 Lambda 函数,后者通过 RDS 代理进一步连接到 RDS for MySQL 数据库。

借助 Amazon RDS,您可以使用 Microsoft SQL Server、MariaDB、MySQL、Oracle Database 和 PostgreSQL 等常见数据库产品在云中运行托管式关系数据库。通过使用 Lambda 访问您的数据库,您可以读取和写入数据以响应事件,例如在您的网站上注册的新客户。您的函数、数据库实例和代理可以自动扩展以满足高需求时段。

要完成本教程,请执行以下任务:

  1. 在您的 Amazon Web Services 账户的原定设置 VPC 中启动 RDS for MySQL 数据库实例和代理。

  2. 创建并测试 Lambda 函数,该函数在您的数据库中创建新表并将数据写入其中。

  3. 创建 Amazon SQS 队列并将其配置为在添加新消息时调用您的 Lambda 函数。

  4. 使用 Amazon Web Services Management Console向队列添加消息并使用 CloudWatch Logs 监控结果,来测试完整设置。

通过完成这些步骤,您将学习:

  • 如何使用 Amazon RDS 创建数据库实例和代理,并将 Lambda 函数连接到代理。

  • 如何使用 Lambda 对 Amazon RDS 数据库执行创建和读取操作。

  • 如何使用 Amazon SQS 调用 Lambda 函数。

您可以使用 Amazon Web Services Management Console 或 Amazon Command Line Interface (Amazon CLI) 完成此教程。

先决条件

在开始之前,请完成以下各节中的步骤:

创建 Amazon RDS 数据库实例


        向您显示创建数据库步骤的教程工作流程图。

Amazon RDS 数据库实例是在 Amazon Web Services 云 中运行的独立数据库环境。实例可以包含一个或多个由用户创建的数据库。除非您另行指定,否则 Amazon RDS 会在您的 Amazon Web Services 账户包含的原定设置 VPC 中创建新的数据库实例。有关 Amazon VPC 的更多信息,请参阅 Amazon Virtual Private Cloud 用户指南

在本教程中,您在您 Amazon Web Services 账户 的默认 VPC 中创建一个新实例,并在该实例中创建一个名为 ExampleDB 的数据库。您可以使用 Amazon Web Services Management Console或 Amazon CLI 创建数据库实例和数据库。

创建数据库实例
  1. 打开 Amazon RDS 控制台并选择创建数据库

  2. 保持标准创建选项处于选中状态,然后在引擎选项中选择 MySQL

  3. 模板部分中,选择免费套餐

  4. 设置中,为 DB 实例标识符输入 MySQLForLambda

  5. 请通过执行以下操作设置用户名和密码:

    1. 凭证设置中,将主用户名设置为 admin

    2. 对于主密码,输入并确认密码以访问您的数据库。

  6. 通过执行以下操作指定数据库名称:

    • 将所有剩余的原定设置选项保持选中状态,然后向下滚动到其他配置部分。

    • 展开此部分并输入 ExampleDB 作为初始数据库名称

  7. 保持所有其余默认选项处于选中状态,然后选择创建队列

创建 Lambda 函数和代理


        教程工作流程图显示您正在 Lambda 函数步骤中创建执行角色。

您可以使用 RDS 控制台在与数据库相同的 VPC 中创建 Lambda 函数和代理。

注意

只有在数据库完成创建并处于可用状态时,才能创建这些关联的资源。

创建关联函数和代理
  1. 数据库页面,检查您的数据库是否处于可用状态。如果是,请继续执行下一步。否则,请等到您的数据库变为可用。

  2. 选择您的数据库,并从操作中选择设置 Lambda 连接

  3. 设置 Lambda 连接页面上,选择创建新函数

    新的 Lambda 函数名称设置为 LambdaFunctionWithRDS

  4. RDS 代理部分,选择使用 RDS 代理进行连接选项。进一步选择创建新代理

    • 对于数据库凭证,选择数据库用户名和密码

    • 对于用户名,指定 admin

    • 对于密码,输入您为数据库实例创建的密码。

  5. 选择设置以完成代理和 Lambda 函数的创建。

向导完成设置,并提供指向 Lambda 控制台的链接以查看您的新函数。在切换到 Lambda 控制台之前,请记下代理端点。

创建函数执行角色


        教程工作流程图显示您正在 Lambda 函数步骤中创建执行角色。

在创建 Lambda 函数之前,您需要创建一个执行角色来为您的函数提供必要的权限。在本教程中,Lambda 需要权限来管理与包含您数据库实例的 VPC 的网络连接,以及轮询来自 Amazon SQS 队列的消息。

为了向您的 Lambda 函数提供其所需的权限,本教程使用 IAM 托管策略。这些策略可授予许多常见使用案例的权限,可在您的 Amazon Web Services 账户 中使用。有关使用托管策略的更多信息,请参阅 策略最佳实践

创建 Lambda 执行角色
  1. 打开 IAM 控制台的角色页面,然后选择创建角色

  2. 对于受信任的实体类型,选择 Amazon 服务,对于使用案例,选择 Lambda

  3. 选择下一步

  4. 通过执行以下操作添加 IAM 托管策略:

    1. 使用策略搜索框,搜索 AWSLambdaSQSQueueExecutionRole

    2. 在结果列表中,选中角色旁的复选框,然后选择清除筛选条件

    3. 使用策略搜索框,搜索 AWSLambdaVPCAccessExecutionRole

    4. 在结果列表中,选中角色旁的复选框,然后选择下一步

  5. 对于角色名称,输入 lambda-vpc-sqs-role,然后选择创建角色

在本教程的后面部分,您需要提供刚刚创建的执行角色的 Amazon 资源名称(ARN)。

查找执行角色 ARN
  1. 打开 IAM 控制台的角色页面,然后选择您的角色(lambda-vpc-sqs-role)。

  2. 复制摘要部分中显示的 ARN

创建 Lambda 部署包


        教程工作流程图显示您正在 Lambda 函数步骤中创建部署包。

以下示例 Python 代码使用 PyMySQL 包打开与您的数据库的连接。首次调用函数时,它还会创建一个名为 Customer 的新表。该表使用以下架构,其中 CustID 是主键:

Customer(CustID, Name)

该函数还使用 PyMySQL 向该表添加记录。该函数使用您将添加到 Amazon SQS 队列的消息中指定的客户 ID 和名称来添加记录。

该代码在处理程序函数之外创建了与数据库的连接。在初始化代码中创建连接,使后续调用能够重用该连接并提高性能。在生产应用程序中,您还可以使用预置并发来初始化所请求数量的数据库连接。调用函数后,这些连接即可用。

import sys import logging import pymysql import json import os # rds settings user_name = os.environ['USER_NAME'] password = os.environ['PASSWORD'] rds_proxy_host = os.environ['RDS_PROXY_HOST'] db_name = os.environ['DB_NAME'] logger = logging.getLogger() logger.setLevel(logging.INFO) # create the database connection outside of the handler to allow connections to be # re-used by subsequent function invocations. try: conn = pymysql.connect(host=rds_proxy_host, user=user_name, passwd=password, db=db_name, connect_timeout=5) except pymysql.MySQLError as e: logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.") logger.error(e) sys.exit(1) logger.info("SUCCESS: Connection to RDS for MySQL instance succeeded") def lambda_handler(event, context): """ This function creates a new RDS database table and writes records to it """ message = event['Records'][0]['body'] data = json.loads(message) CustID = data['CustID'] Name = data['Name'] item_count = 0 sql_string = f"insert into Customer (CustID, Name) values({CustID}, '{Name}')" with conn.cursor() as cur: cur.execute("create table if not exists Customer ( CustID int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (CustID))") cur.execute(sql_string) conn.commit() cur.execute("select * from Customer") logger.info("The following items have been added to the database:") for row in cur: item_count += 1 logger.info(row) conn.commit() return "Added %d items to RDS for MySQL table" %(item_count)
注意

在此示例中,您的数据库访问凭证将存储为环境变量。在生产应用程序中,建议您将 Amazon Secrets Manager 用作更安全的选项。请注意,如果 Lambda 函数位于 VPC 中,您需要创建 VPC 端点才能连接到 Secrets Manager。要了解更多信息,请参阅如何在虚拟私有云中连接到 Secrets Manager 服务

要在函数代码中包含 PyMySQL 依赖关系,请创建一个 .zip 部署包。以下命令适用于 Linux、macOS 或 Unix:

创建 .zip 部署包
  1. 将代码示例保存为名为 lambda_function.py 的文件。

  2. 在创建 lambda_function.py 文件的同一目录中,创建一个名为 package 的新目录并安装 PyMySQL 库。

    mkdir package pip install --target package pymysql
  3. 创建一个包含您的应用程序代码和 PyMySQL 库的 zip 文件。在 Linux 或 MacOS 中,运行以下 CLI 命令。在 Windows 中,使用您首选的压缩工具来创建 lambda_function.zip 文件。您的 lambda_function.py 源代码文件和包含依赖项的文件夹必须安装在.zip 文件的根目录下。

    cd package zip -r ../lambda_function.zip . cd .. zip lambda_function.zip lambda_function.py

    您也可以使用 Python 虚拟环境创建部署包。参阅使用 .zip 文件归档部署 Python Lambda 函数

更新 Lambda 函数

现在,您可以使用刚创建的 .zip 程序包,通过 Lambda 控制台更新 Lambda 函数。要支持函数访问数据库,您还需要使用访问凭证配置环境变量。

更新 Lambda 函数
  1. 打开 Lambda 控制台的函数页面,然后选择您的函数 LambdaFunctionWithRDS

  2. 运行时系统设置选项卡中,选择编辑,以将函数的运行时系统更改为 Python 3.10

  3. 处理程序更改为 lambda_function.lambda_handler

  4. 代码选项卡中,选择上传自,然后选择 .zip 文件

  5. 选择您在前一阶段创建的 lambda_function.zip 文件,然后选择保存

现在,使用您之前创建的执行角色来配置该函数。这会授予该函数访问您的数据库实例和轮询 Amazon SQS 队列所需的权限。

配置函数的执行角色
  1. 在 Lambda 控制台的函数页面中,选择配置选项卡,然后选择权限

  2. 执行角色中,选择编辑

  3. 现有角色中,选择您的执行角色(lambda-vpc-sqs-role)。

  4. 选择 Save(保存)。

配置函数的环境变量
  1. 在 Lambda 控制台的函数页面中,选择配置选项卡,然后选择环境变量

  2. 选择编辑

  3. 要添加数据库访问凭证,请执行以下操作:

    1. 选择添加环境变量,然后为输入 USER_NAME,并为输入 admin

    2. 选择添加环境变量,然后为输入 DB_NAME,并为输入 ExampleDB

    3. 选择添加环境变量,然后为输入 PASSWORD,并为输入您在创建数据库时选择的密码。

    4. 选择添加环境变量,然后为输入 RDS_PROXY_HOST,并为输入您之前记下的 RDS 代理端点。

    5. 选择 Save(保存)。

在控制台中测试 Lambda 函数。


        教程工作流程图显示您正在 Lambda 函数步骤中测试函数。

您现在可以使用 Lambda 控制台测试您的函数。您可以创建一个测试事件,该事件模仿您在教程的最后阶段使用 Amazon SQS 调用函数时将收到的数据。您的测试事件包含一个 JSON 对象,该对象指定要添加到您的函数创建的 Customer 表中的客户 ID 和客户名称。

测试 Lambda 函数
  1. 打开 Lambda 控制台的函数页面,然后选择一个函数。

  2. 选择测试部分。

  3. 选择创建新事件,然后输入 myTestEvent 作为事件名称。

  4. 将以下代码复制到事件 JSON 中,然后选择保存

    { "Records": [ { "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "body": "{\n \"CustID\": 1021,\n \"Name\": \"Martha Rivera\"\n}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1545082649183", "SenderId": "AIDAIENQZJOLO23YVJ4VO", "ApproximateFirstReceiveTimestamp": "1545082649185" }, "messageAttributes": {}, "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-west-2:123456789012:my-queue", "awsRegion": "us-west-2" } ] }
  5. 选择测试

执行结果选项卡中,您应该看到与函数日志中显示的以下内容类似的结果:

[INFO] 2023-02-14T19:31:35.149Z bdd06682-00c7-4d6f-9abb-89f4bbb4a27f The following items have been added to the database: [INFO] 2023-02-14T19:31:35.149Z bdd06682-00c7-4d6f-9abb-89f4bbb4a27f (1021, 'Martha Rivera')

创建 Amazon SQS 队列


        教程工作流程图显示您正在消息队列步骤中创建队列。

您已成功测试了您的 Lambda 函数和 Amazon RDS 数据库实例的集成。现在,您创建了 Amazon SQS 队列,用于在本教程的最后阶段调用 Lambda 函数。

创建 Amazon SQS 队列(控制台)。
  1. 打开 Amazon SQS 控制台的队列页面,然后选择创建队列

  2. 类型保留为标准,然后为您的队列名称输入 LambdaRDSQueue

  3. 保持所有默认选项处于选中状态,然后选择创建队列

创建一个事件源映射以调用您的 Lambda 函数


        教程工作流程图显示您正在消息队列步骤中创建事件源映射。

事件源映射是 Lambda 中的一种资源,它从流或队列中读取项目并调用 Lambda 函数。配置事件源映射时,可以指定批处理大小,以便可以将来自您的流或队列的记录批处理成单个负载。在此示例中,您将批处理大小设置为 1,这样每次向队列发送消息时都会调用 Lambda 函数。您可以使用 Amazon CLI 或 Lambda 控制台配置事件源映射。

创建事件源映射(控制台)
  1. 打开 Lambda 控制台的函数页面,然后选择一个函数 (LambdaFunctionWithRDS)。

  2. 函数概述部分中,选择添加触发器

  3. 对于源,选择 Amazon SQS,然后选择队列的名称(LambdaRDSQueue)。

  4. 对于批处理大小,输入 1

  5. 将所有其他选项设置为默认值,然后选择添加

现在,您可以通过向 Amazon SQS 队列添加一条消息来测试您的完整设置。

测试和监控您的设置


        教程工作流程图显示您处于测试和监控步骤。

要测试您的完整设置,请使用控制台向 Amazon SQS 队列添加消息。然后,您可以使用 CloudWatch Logs 确认您的 Lambda 函数正在按预期将记录写入数据库。

测试和监控您的设置
  1. 打开 Amazon SQS 控制台的队列页面,然后选择创建队列 (LambdaRDSQueue)。

  2. 选择发送和接收消息,然后将以下 JSON 粘贴到发送消息部分的消息正文中。

    { "CustID": 1054, "Name": "Richard Roe" }
  3. 选择 Send message(发送消息)。

    将您的消息发送到队列将导致 Lambda 通过您的事件源映射调用您的函数。要确认 Lambda 已按预期调用您的函数,请使用 CloudWatch Logs 验证该函数是否已将客户名称和 ID 写入您的数据库表。

  4. 打开 CloudWatch 控制台的日志组页面,为您的函数选择日志组 (/aws/lambda/LambdaFunctionWithRDS)。

  5. 日志流部分中,选择最新的日志流。

    您的表应包含两条客户记录,每次调用您的函数都有一条记录。在日志流中,您应看到类似以下内容的消息:

    [INFO] 2023-02-14T19:06:43.873Z 45368126-3eee-47f7-88ca-3086ae6d3a77 The following items have been added to the database: [INFO] 2023-02-14T19:06:43.873Z 45368126-3eee-47f7-88ca-3086ae6d3a77 (1021, 'Martha Rivera') [INFO] 2023-02-14T19:06:43.873Z 45368126-3eee-47f7-88ca-3086ae6d3a77 (1054, 'Richard Roe')

清除资源

除非您想要保留为本教程创建的资源,否则可立即将其删除。通过删除您不再使用的 Amazon 资源,可防止您的 Amazon 账户产生不必要的费用。

删除 Lambda 函数
  1. 打开 Lamba 控制台的 Functions(函数)页面

  2. 选择您创建的函数。

  3. 依次选择 Actions(操作)和 Delete(删除)。

  4. 选择 Delete(删除)。

删除执行角色
  1. 打开 IAM 控制台的角色页面

  2. 选择您创建的执行角色。

  3. 选择 Delete role(删除角色)。

  4. 选择 Yes, delete(是,删除)。

删除 MySQL 数据库实例
  1. 打开 Amazon RDS 控制台的 Databases(数据库)页面

  2. 选择您创建的数据库。

  3. 依次选择 Actions(操作)和 Delete(删除)。

  4. 清除 Create final snapshot(创建最终快照)复选框。

  5. 在文本框中输入 delete me

  6. 选择删除

删除 Amazon SQS 队列
  1. 登录到 Amazon Web Services Management Console 并打开 Amazon SQS 控制台,网址:https://console.aws.amazon.com/vpc/

  2. 选择创建的队列。

  3. 选择 Delete(删除)。

  4. 在文本框中输入 delete

  5. 选择 Delete