您可以将 Lambda 函数直接连接到 Amazon Relational Database Service(Amazon RDS),也可以通过 Amazon RDS 代理连接。直接连接适用于简单的场景,而在生产中则推荐使用代理。数据库代理管理共享数据库连接池,从而让函数能够在不耗尽数据库连接的情况下达到高并发级别。
对于频繁建立短数据库连接或打开和关闭大量数据库连接的 Lambda 函数,我们建议使用 Amazon RDS 代理。有关更多信息,请参阅《Amazon Relational Database Service 开发人员指南》中的自动连接 Lambda 函数和数据库实例。
要将 Lambda 函数快速连接到 Amazon RDS 数据库,您可以使用控制台内的引导式向导。要打开向导,执行以下操作:
打开 Lamba 控制台的函数页面
。 -
选择要将数据库连接到其中的函数。
-
在配置选项卡上,选择 RDS 数据库。
-
选择连接到 RDS 数据库。
将函数连接到数据库后,您可以通过选择添加代理来创建代理。
提示
对于许多无服务器应用场景,Amazon DynamoDB 可能是比 Amazon RDS 更好的选项。如果您不确定哪种数据库服务最适合您的特定应用场景,则请参阅 为基于 Lambda 的应用程序选择数据库服务。
配置函数以使用 RDS 资源
在 Lambda 控制台中,您可以预置和配置 Amazon RDS 数据库实例和代理资源。您可以导航到配置选项卡下的 RDS 数据库完成此操作。或者,您也可以在 Amazon RDS 控制台中创建和配置到 Lambda 函数的连接。配置 RDS 数据库实例以便与 Lambda 配合使用时,请注意以下条件:
-
要连接到数据库,您的函数必须位于数据库在其中运行的 Amazon VPC。
-
您可以将 Amazon RDS 数据库与 MySQL、MariaDB、PostgreSQL 或 Microsoft SQL Server 引擎一起使用。
-
您也可以将 Aurora 数据库集群与 MySQL 或 PostgreSQL 引擎一起使用。
-
您需要提供用于数据库身份验证的 Secrets Manager 密钥。
-
IAM 角色必须提供使用密钥的权限和必须允许 Amazon RDS 代入角色的信任策略。
-
使用控制台配置 Amazon RDS 资源并将其连接到函数的 IAM 主体必须具有以下权限:
注意
只有在配置 Amazon RDS 代理来管理数据库连接池时,才需要 Amazon RDS 代理权限。
例 权限策略
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:CreateSecurityGroup", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "ec2:AuthorizeSecurityGroupIngress", "ec2:AuthorizeSecurityGroupEgress", "ec2:RevokeSecurityGroupEgress", "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", "ec2:DescribeNetworkInterfaces" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "rds-db:connect", "rds:CreateDBProxy", "rds:CreateDBInstance", "rds:CreateDBSubnetGroup", "rds:DescribeDBClusters", "rds:DescribeDBInstances", "rds:DescribeDBSubnetGroups", "rds:DescribeDBProxies", "rds:DescribeDBProxyTargets", "rds:DescribeDBProxyTargetGroups", "rds:RegisterDBProxyTargets", "rds:ModifyDBInstance", "rds:ModifyDBProxy" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "lambda:CreateFunction", "lambda:ListFunctions", "lambda:UpdateFunctionConfiguration" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "iam:AttachRolePolicy", "iam:AttachPolicy", "iam:CreateRole", "iam:CreatePolicy" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds", "secretsmanager:CreateSecret" ], "Resource": "*" } ] }
Amazon RDS 根据数据库实例大小按小时收取代理费率,详情请参阅 RDS 代理定价
Lambda 和 Amazon RDS 设置
Lambda 和 Amazon RDS 控制台都将协助您自动配置一些必要资源,以便在 Lambda 和 Amazon RDS 之间建立连接。
使用 Lambda 函数连接到 Amazon RDS 数据库
以下代码示例显示如何实现连接到 Amazon RDS 数据库的 Lambda 函数。该函数发出一个简单的数据库请求并返回结果。
- 适用于 .NET 的 SDK
-
注意
查看 GitHub,了解更多信息。在无服务器示例
存储库中查找完整示例,并了解如何进行设置和运行。 在 Lambda 函数中使用 .NET 连接到 Amazon RDS 数据库。
using System.Data; using System.Text.Json; using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.Core; using MySql.Data.MySqlClient; // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace aws_rds; public class InputModel { public string key1 { get; set; } public string key2 { get; set; } } public class Function { /// <summary> // Handles the Lambda function execution for connecting to RDS using IAM authentication. /// </summary> /// <param name="input">The input event data passed to the Lambda function</param> /// <param name="context">The Lambda execution context that provides runtime information</param> /// <returns>A response object containing the execution result</returns> public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context) { // Sample Input: {"body": "{\"key1\":\"20\", \"key2\":\"25\"}"} var input = JsonSerializer.Deserialize<InputModel>(request.Body); /// Obtain authentication token var authToken = RDSAuthTokenGenerator.GenerateAuthToken( Environment.GetEnvironmentVariable("RDS_ENDPOINT"), Convert.ToInt32(Environment.GetEnvironmentVariable("RDS_PORT")), Environment.GetEnvironmentVariable("RDS_USERNAME") ); /// Build the Connection String with the Token string connectionString = $"Server={Environment.GetEnvironmentVariable("RDS_ENDPOINT")};" + $"Port={Environment.GetEnvironmentVariable("RDS_PORT")};" + $"Uid={Environment.GetEnvironmentVariable("RDS_USERNAME")};" + $"Pwd={authToken};"; try { await using var connection = new MySqlConnection(connectionString); await connection.OpenAsync(); const string sql = "SELECT @param1 + @param2 AS Sum"; await using var command = new MySqlCommand(sql, connection); command.Parameters.AddWithValue("@param1", int.Parse(input.key1 ?? "0")); command.Parameters.AddWithValue("@param2", int.Parse(input.key2 ?? "0")); await using var reader = await command.ExecuteReaderAsync(); if (await reader.ReadAsync()) { int result = reader.GetInt32("Sum"); //Sample Response: {"statusCode":200,"body":"{\"message\":\"The sum is: 45\"}","isBase64Encoded":false} return new APIGatewayProxyResponse { StatusCode = 200, Body = JsonSerializer.Serialize(new { message = $"The sum is: {result}" }) }; } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } return new APIGatewayProxyResponse { StatusCode = 500, Body = JsonSerializer.Serialize(new { error = "Internal server error" }) }; } }
处理来自 Amazon RDS 的事件通知
您可以使用 Lambda 处理 Amazon RDS 数据库中的事件通知。Amazon RDS 将通知发送到 Amazon Simple Notification Service (Amazon SNS) 主题,您可以将其配置为调用 Lambda 函数。Amazon SNS 将来自 Amazon RDS 的消息封装在其自己的事件文档中,并将其发送到您的函数。
有关配置 Amazon RDS 数据库以发送通知的详细信息,请参阅使用 Amazon RDS 事件通知。
例 Amazon SNS 事件中的 Amazon RDS 消息
{ "Records": [ { "EventVersion": "1.0", "EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:rds-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "EventSource": "aws:sns", "Sns": { "SignatureVersion": "1", "Timestamp": "2023-01-02T12:45:07.000Z", "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "Message":
"{\"Event Source\":\"db-instance\",\"Event Time\":\"2023-01-02 12:45:06.000\",\"Identifier Link\":\"https://console.aws.amazon.com/rds/home?region=eu-west-1#dbinstance:id=dbinstanceid\",\"Source ID\":\"dbinstanceid\",\"Event ID\":\"http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/USER_Events.html#RDS-EVENT-0002\",\"Event Message\":\"Finished DB Instance backup\"}",
"MessageAttributes": {}, "Type": "Notification", "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "TopicArn":"arn:aws:sns:us-east-2:123456789012:sns-lambda", "Subject": "RDS Notification Message" } } ] }
Lambda 和 Amazon RDS 完整教程
-
使用 Lambda 函数访问 Amazon RDS 数据库:在《Amazon RDS 用户指南》中,了解如何使用 Lambda 函数通过 Amazon RDS 代理将数据写入 Amazon RDS 数据库。Lambda 函数将从 Amazon SQS 队列中读取记录,每当添加消息时,都将新的项目写入数据库的表中。