从 Aurora PostgreSQL 数据库集群中调用 Amazon Lambda 函数
Amazon Lambda 是事件驱动型计算服务,无需您预置或管理服务器即可运行代码。该服务可与许多 Amazon 服务搭配使用,其中包括 Aurora PostgreSQL。例如,您可以使用 Lambda 函数处理来自数据库的事件通知,或者在将新文件上传到 Amazon S3 时从文件中加载数据。若要了解 Lambda 的更多信息,请参阅《Amazon Lambda 开发人员指南》中的什么是 Amazon Lambda?
Aurora PostgreSQL 11.9 及更高版本支持调用 Amazon Lambda 函数。
设置 Aurora PostgreSQL 使用 Lambda 函数的过程包含多个步骤,其中涉及 Amazon Lambda、IAM、VPC 和 Aurora PostgreSQL 数据库集群。下文对必要步骤进行了总结。
有关 Lambda 函数的更多信息,请参阅《Amazon 开发人员指南https://docs.amazonaws.cn/lambda/latest/dg/getting-started.html》中的 Lambda 入门和 Amazon Lambda Lambda 函数。
主题
步骤 1:配置 Aurora PostgreSQL 数据库集群,实现与 Amazon Lambda 的出站连接
Lambda 函数始终在 Amazon Lambda 服务拥有的 Amazon VPC 中运行。Lambda 将向此 VPC 应用网络访问和安全规则,并且会自动维护和监控 VPC。Aurora PostgreSQL 数据库集群需要向 Lambda 服务的 VPC 发送网络流量。其配置方式取决于 Aurora 数据库集群的主数据库实例是公有实例,还是私有实例。
如果 Aurora PostgreSQL 数据库集群 为公有,则只需配置安全组以允许来自 VPC 的出站流量。如果数据库集群的主数据库实例位于 VPC 的公有子网中,且实例的 PubliclyAccessible 属性为
true
,则其为公有实例。若要查找此属性的值,您可以使用 describe-db-instances Amazon CLI 命令。您也可以使用 Amazon Web Services Management Console 打开 Connectivity & security(连接和安全性)选项卡,然后检查 Publicly accessible(公开访问)是否为 Yes(是)。您还可以使用 Amazon Web Services Management Console 和 Amazon CLI 检查实例是否在 VPC 的公有子网中。
如果 Aurora PostgreSQL 数据库集群为私有,则您有几种选择。您可以使用网络地址转换 (NAT) 网关 或 VPC 终端节点。有关 NAT 网关的更多信息,请参阅 NAT 网关。下面是使用 VPC 终端节点的步骤汇总。
为公有数据库实例配置与 Amazon Lambda 的连接
配置运行 Aurora PostgreSQL 数据库集群的 VPC 来允许出站连接。您可以在 VPC 安全组上创建出站规则来完成配置,该规则允许 TCP 流量流向端口 443 和任何 IPv4 地址 (0.0.0.0/0)。
为私有数据库实例配置与 Amazon Lambda 的连接
使用 VPC 终端节点为 Amazon Lambda 配置 VPC。有关更多信息,请参阅《Amazon VPC 用户指南https://docs.amazonaws.cn/vpc/latest/userguide/vpc-endpoints.html》中的 VPC 终端节点。该端点会返回 Aurora PostgreSQL 数据库集群向 Lambda 函数发出的调用的响应。
将端点添加到 VPC 路由表中。有关更多信息,请参阅《Amazon VPC 用户指南》中的使用路由表。
您的 VPC 现在可以在网络级别与 Amazon Lambda VPC 交互。不过,您仍然需要使用 IAM 配置权限。
步骤 2:为 Aurora PostgreSQL 数据库集群和 Amazon Lambda 配置 IAM
从 Aurora PostgreSQL 数据库集群调用 Lambda 函数需要特定权限。若要配置必要权限,建议创建允许调用 Lambda 函数的 IAM 策略,将该策略分配给一个角色,然后将该角色应用于数据库集群。这种方法授予数据库集群代表您调用指定 Lambda 函数的权限。以下步骤说明如何使用 Amazon CLI 执行此操作。
配置 IAM 权限以将集群与 Lambda 搭配使用
使用 create-policy
Amazon CLI 命令创建允许 Aurora PostgreSQL 数据库集群调用指定 Lambda 函数的 IAM 策略。(语句 ID (Sid) 是策略语句的可选描述,对使用没有影响。) 此策略授予 Aurora 数据库集群调用指定 Lambda 函数所需的最低权限。 aws iam create-policy --policy-name
rds-lambda-policy
--policy-document '{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToExampleFunction", "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:
" } ] }'aws-region
:444455556666:function:my-function您也可以使用允许您调用任何 Lambda 函数的预定义
AWSLambdaRole
策略。有关更多信息,请参阅 Lambda 的基于身份的 IAM 策略使用 create-role
Amazon CLI 命令创建该策略可在运行时担任的 IAM 角色。 aws iam create-role --role-name
rds-lambda-role
--assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }'使用 attach-role-policy
Amazon CLI 命令将策略应用于角色。 aws iam attach-role-policy \ --policy-arn arn:aws:iam::
444455556666
:policy/rds-lambda-policy
\ --role-namerds-lambda-role
--regionaws-region
使用 add-role-to-db-cluster
Amazon CLI 命令,将该角色应用于 Aurora PostgreSQL 数据库集群。最后一步允许数据库集群的数据库用户调用 Lambda 函数。 aws rds add-role-to-db-cluster \ --db-cluster-identifier
my-cluster-name
\ --feature-name Lambda \ --role-arn arn:aws:iam::444455556666:role/rds-lambda-role
\ --regionaws-region
完成 VPC 和 IAM 配置后,便可以安装 aws_lambda
扩展。(请注意,您可以随时安装扩展,但只有在您设置正确的 VPC 支持和 IAM 权限之后,aws_lambda
扩展才会对 Aurora PostgreSQL 数据库集群的功能添加内容。)
步骤 3:为 Aurora PostgreSQL 数据库集群安装 aws_lambda
扩展
要将 Amazon Lambda 与 Aurora PostgreSQL 数据库集群搭配使用,请将 aws_lambda
PostgreSQL 扩展安装到 Aurora PostgreSQL。此扩展允许 Aurora PostgreSQL 数据库集群能从 PostgreSQL 调用 Lambda 函数。
为 Aurora PostgreSQL 数据库集群安装 aws_lambda
扩展
使用 PostgreSQL psql
命令行或 pgAdmin 工具连接到 Aurora PostgreSQL 数据库集群。
以具有
rds_superuser
权限的用户身份,连接到 Aurora PostgreSQL 数据库集群。默认postgres
用户如示例所示。psql -h
cluster-instance.444455556666.
.rds.amazonaws.com -U postgres -p 5432aws-region
-
安装
aws_lambda
扩展。aws_commons
扩展也是必要项。其为 PostgreSQL 的aws_lambda
和许多其他 Aurora 扩展提供帮助程序函数。如果其尚未安装到 Aurora PostgreSQL 数据库集群上,则会按如下所示一并安装该扩展和aws_lambda
。CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;
NOTICE: installing required extension "aws_commons" CREATE EXTENSION
aws_lambda
扩展已安装在 Aurora PostgreSQL 数据库集群的主数据库实例中。现在,您可以创建易于使用结构来调用 Lambda 函数。
步骤 4:将 Lambda 帮助程序函数与 Aurora PostgreSQL 数据库集群搭配使用(可选)
您可以使用 aws_commons
扩展中的帮助程序函数来准备实体,以便更轻松地从 PostgreSQL 调用这些实体。为此,您需要获得有关 Lambda 函数的以下信息:
-
Function name(函数名称):Lambda 函数的名称、Amazon Resource Name (ARN)、版本或别名。在 步骤 2:为集群和 Lambda 配置 IAM 中创建的 IAM 策略需要 ARN,所以建议您使用函数的 ARN。
-
Amazon Region(Amazon 区域):(可选)如果其与 Aurora PostgreSQL 数据库集群 不在同一个区域中,则此区域为 Lambda 函数所在的 Amazon 区域。
您可以使用 aws_commons.create_lambda_function_arn 函数保存 Lambda 函数名称信息。此帮助程序函数创建了 aws_commons._lambda_function_arn_1
复合结构,其中包含调用函数所需的详细信息。在下文中,您可以找到三种替代方法来设置此复合结构。
SELECT aws_commons.create_lambda_function_arn( 'my-function', '
aws-region
' ) AS aws_lambda_arn_1 \gset
SELECT aws_commons.create_lambda_function_arn( '111122223333:function:my-function', '
aws-region
' ) AS lambda_partial_arn_1 \gset
SELECT aws_commons.create_lambda_function_arn( 'arn:aws:lambda:
aws-region
:111122223333:function:my-function' ) AS lambda_arn_1 \gset
这些值均可用于 aws_lambda.invoke 函数调用。有关示例,请参阅 步骤 5:从 Aurora PostgreSQL 数据库集群调用 Lambda 函数。
步骤 5:从 Aurora PostgreSQL 数据库集群调用 Lambda 函数
aws_lambda.invoke
函数采用同步还是异步调用方式取决于 invocation_type
。此参数的两个可用选项分别为 RequestResponse
(默认)和 Event
,如下所示。
-
RequestResponse
:此为同步调用类型。如果调用时未指定调用类型,默认此调用方式。响应有效负载包含aws_lambda.invoke
函数的结果。如果工作流程需要接收 Lambda 函数的结果才能继续进行操作,请使用此调用类型。 -
Event
:此为异步调用类型。响应不包含包含结果的有效负载。如果工作流程不需要 Lambda 函数的结果即可继续进行操作,请使用此调用类型。
要对设置进行简单测试,您可以使用 psql
连接到数据库实例,然后从命令行调用示例函数。假设在 Lambda 服务上设置了一个基本函数,例如下面屏幕截图中所示的简单 Python 函数。

调用示例函数
使用
psql
或 pgAdmin 连接到主数据库实例。psql -h
cluster.444455556666.
.rds.amazonaws.com -U postgres -p 5432aws-region
使用函数的 ARN 调用该函数。
SELECT * from aws_lambda.invoke(aws_commons.create_lambda_function_arn('arn:aws:lambda:
aws-region
:444455556666:function:simple', 'us-west-1'), '{"body": "Hello from Postgres!"}'::json );响应如下所示。
status_code | payload | executed_version | log_result -------------+-------------------------------------------------------+------------------+------------ 200 | {"statusCode": 200, "body": "\"Hello from Lambda!\""} | $LATEST | (1 row)
如果调用尝试不成功,请参阅 Lambda 函数错误消息 。
在下文中,您可以找到调用 aws_lambda.invoke 函数的一些示例。大多数示例都使用您在 步骤 4:将 Lambda 帮助程序函数与 Aurora PostgreSQL 数据库集群搭配使用(可选) 中创建的复合结构 aws_lambda_arn_1
来简化函数详细信息的传递。有关异步调用的示例,请参阅 示例:Lambda 函数的异步(事件)调用。列出的其他示例均使用同步调用。
要了解有关 Lambda 调用类型的更多信息,请参阅《Amazon Lambda 开发人员指南》中的调用 Lambda 函数。有关 aws_lambda_arn_1
的更多信息,请参阅 aws_commons.create_lambda_function_arn。
示例列表
示例:Lambda 函数的同步 (RequestResponse) 调用
以下是 Lambda 函数同步调用的两个示例。这些 aws_lambda.invoke
函数调用的结果相同。
SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json);
SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse');
参数如下所述:
-
:'aws_lambda_arn_1'
:此参数使用aws_commons.create_lambda_function_arn
帮助程序函数标识在 步骤 4:将 Lambda 帮助程序函数与 Aurora PostgreSQL 数据库集群搭配使用(可选) 中创建的复合结构。您还可以通过内联方式在aws_lambda.invoke
调用中创建此结构,如下所示。SELECT * FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('my-function', '
aws-region
'), '{"body": "Hello from Postgres!"}'::json ); -
'{"body": "Hello from PostgreSQL!"}'::json
– 要传递到 Lambda 函数的 JSON 负载。 -
'RequestResponse'
– Lambda 调用类型。
示例:Lambda 函数的异步(事件)调用
以下是异步 Lambda 函数调用的示例。Event
调用类型使用指定的输入负载计划 Lambda 函数调用并立即返回。在某些不依赖于 Lambda 函数结果的工作流程中使用 Event
调用类型。
SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'Event');
示例:在函数响应中捕获 Lambda 执行日志
您可以使用 aws_lambda.invoke
函数调用中的 log_type
参数,在函数响应中包含执行日志的最后 4 kB。默认情况下,此参数设置为 None
,但您可以指定 Tail
在响应中捕获 Lambda 执行日志的结果,如下所示。
SELECT *, select convert_from(decode(log_result, 'base64'), 'utf-8') as log FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'Tail');
将 aws_lambda.invoke 函数的 log_type
参数设置为 Tail
,以在响应中包含执行日志。log_type
参数的默认值为 None
。
返回的 log_result
是 base64
编码的字符串。您可以使用 decode
和 convert_from
PostgreSQL 函数的组合来解码内容。
有关 log_type
的更多信息,请参阅 aws_lambda.invoke。
示例:在 Lambda 函数中包含客户端上下文
aws_lambda.invoke
函数具有 context
参数,可用于传递独立于有效负载的信息,如下所示。
SELECT *, convert_from(decode(log_result, 'base64'), 'utf-8') as log FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'Tail');
要包含客户端上下文,请将 JSON 对象用于 aws_lambda.invoke 函数的 context
参数。
有关 context
参数的更多信息,请参阅 aws_lambda.invoke 参考。
示例:调用 Lambda 函数的特定版本
通过在 aws_lambda.invoke
调用中包含 qualifier
参数,您可以指定 Lambda 函数的特定版本。在下文中,您可以找到一个使用 '
作为版本别名完成此操作的示例。custom_version
'
SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'None', NULL, '
custom_version
');
您还可以改为提供包含 Lambda 函数名称详细信息的 Lambda 函数限定符,如下所示。
SELECT * FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('my-function:custom_version', 'us-west-2'), '{"body": "Hello from Postgres!"}'::json);
有关 qualifier
和其他参数的详细信息,请参阅 aws_lambda.invoke 参考。
Lambda 函数错误消息
VPC 配置不当可能导致错误消息,如下所示。
ERROR: invoke API failed DETAIL: Amazon Lambda client returned 'Unable to connect to endpoint'. CONTEXT: SQL function "invoke" statement 1
首先检查 VPC 安全组。确保在端口 443 上打开 TCP 的出站规则,以便 VPC 连接到 Lambda VPC。
如果 Lambda 函数在请求处理过程中抛出异常,则 aws_lambda.invoke
会失败并显示 PostgreSQL 错误,如下所示。
SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json);
ERROR: lambda invocation failed DETAIL: "arn:aws:lambda:us-west-2:555555555555:function:my-function" returned error "Unhandled", details: "<Error details string>".
务必处理 Lambda 函数或 PostgreSQL 应用程序中的错误。