将 DBContext 添加到 AWS Lambda 会导致它挂起
Adding a DBContext to AWS Lambda causes it to hang
我是 C# 和无服务器开发的新手。我正在尝试创建一个具有 API 网关触发器的 AWS Lambda。当 Lambda 触发时,我想将 User
记录写入数据库。
拉姆达:
namespace CreateProfile;
using System.Net;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using Database;
using Users.Models;
public class Function
{
/// <summary>
/// This Lambda function is for creating a user profile
/// </summary>
public APIGatewayHttpApiV2ProxyResponse FunctionHandler(User user, ILambdaContext context)
{
LambdaLogger.Log($"Calling function name: {context.FunctionName}\n");
LambdaLogger.Log($"Payload Received: {user}");
// 1. Populate the relevant table(s) from our input
using myDbContext ctx = new();
ctx.Users.Add(user);
ctx.SaveChanges();
APIGatewayHttpApiV2ProxyResponse response = new ()
{
StatusCode = (int)HttpStatusCode.OK,
Body = "Great Scott...it worked!",
Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
};
return response;
}
}
我正在使用以下程序集:
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(
DefaultLambdaJsonSerializer
))]
我使用以下作为我的数据库上下文:
namespace Database;
using Users.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Npgsql;
[DbConfigurationType(typeof(Config))]
public class MyDbContext: DbContext
{
public myDbContext(): base(MakeConnString()) {}
private static string MakeConnString()
{
// Will be moving these to a common location
string OptEnv(string key, string default_) =>
Environment.GetEnvironmentVariable(key) ?? default_;
string Env(string key) =>
Environment.GetEnvironmentVariable(key) ?? throw new MissingFieldException(key);
NpgsqlConnectionStringBuilder builder = new()
{
Host = Env("PGHOST"),
Port = int.Parse(OptEnv("PGPORT", "5432")),
SslMode = Enum.Parse<SslMode>(OptEnv("PGSSLMODE", "Require")),
TrustServerCertificate = true,
Database = OptEnv("PGDATABASE", "postgres"),
Username = OptEnv("PGUSER", "postgres"),
Password = Env("PGPASSWORD")
};
return builder.ConnectionString;
}
public DbSet<User> Users { get; set; }
}
当 运行 我的 Lambda 挂起时,我不知道为什么。
我假设您尝试与之交互的数据库是 RDS 实例或同一帐户中 EC2 实例上的 运行,对吗?
如果是这样,您的 Lambda 函数是否已部署到您的 VPC 中?如果不是,Lambda 需要是为了与 VPC 资源对话。默认情况下,Lambda 未部署在您的 VPC 中。
如果您使用的是无服务器框架,则需要将以下配置添加到 serverless.yml [https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml][ 的提供程序部分=11=]
provider:
# Optional VPC settings
# If you use VPC then both securityGroupIds and subnetIds are required
vpc:
securityGroupIds:
- securityGroupId1
subnetIds:
- subnetId1
- subnetId2
您引用的子网需要有到您的数据库配置到的子网的路由。它们可以与您的 RDS 实例或 EC2 在数据库中 运行 的子网中。
最后,您需要确保安全组允许 Lambda 安全组的正确端口上的出站流量,以及确保数据库(EC2 或 RDS)上的安全组允许来自Lambda SG 或您要将 Lambda 部署到正确端口 # 的子网的 CIDR/IP 范围。
挂起通常是请求未发送到数据库 - 如果您已经设置了部署在 VPC 中的 Lambda,那么您应该检查提到的路由和安全组。
我是 C# 和无服务器开发的新手。我正在尝试创建一个具有 API 网关触发器的 AWS Lambda。当 Lambda 触发时,我想将 User
记录写入数据库。
拉姆达:
namespace CreateProfile;
using System.Net;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using Database;
using Users.Models;
public class Function
{
/// <summary>
/// This Lambda function is for creating a user profile
/// </summary>
public APIGatewayHttpApiV2ProxyResponse FunctionHandler(User user, ILambdaContext context)
{
LambdaLogger.Log($"Calling function name: {context.FunctionName}\n");
LambdaLogger.Log($"Payload Received: {user}");
// 1. Populate the relevant table(s) from our input
using myDbContext ctx = new();
ctx.Users.Add(user);
ctx.SaveChanges();
APIGatewayHttpApiV2ProxyResponse response = new ()
{
StatusCode = (int)HttpStatusCode.OK,
Body = "Great Scott...it worked!",
Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
};
return response;
}
}
我正在使用以下程序集:
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(
DefaultLambdaJsonSerializer
))]
我使用以下作为我的数据库上下文:
namespace Database;
using Users.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Npgsql;
[DbConfigurationType(typeof(Config))]
public class MyDbContext: DbContext
{
public myDbContext(): base(MakeConnString()) {}
private static string MakeConnString()
{
// Will be moving these to a common location
string OptEnv(string key, string default_) =>
Environment.GetEnvironmentVariable(key) ?? default_;
string Env(string key) =>
Environment.GetEnvironmentVariable(key) ?? throw new MissingFieldException(key);
NpgsqlConnectionStringBuilder builder = new()
{
Host = Env("PGHOST"),
Port = int.Parse(OptEnv("PGPORT", "5432")),
SslMode = Enum.Parse<SslMode>(OptEnv("PGSSLMODE", "Require")),
TrustServerCertificate = true,
Database = OptEnv("PGDATABASE", "postgres"),
Username = OptEnv("PGUSER", "postgres"),
Password = Env("PGPASSWORD")
};
return builder.ConnectionString;
}
public DbSet<User> Users { get; set; }
}
当 运行 我的 Lambda 挂起时,我不知道为什么。
我假设您尝试与之交互的数据库是 RDS 实例或同一帐户中 EC2 实例上的 运行,对吗?
如果是这样,您的 Lambda 函数是否已部署到您的 VPC 中?如果不是,Lambda 需要是为了与 VPC 资源对话。默认情况下,Lambda 未部署在您的 VPC 中。
如果您使用的是无服务器框架,则需要将以下配置添加到 serverless.yml [https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml][ 的提供程序部分=11=]
provider:
# Optional VPC settings
# If you use VPC then both securityGroupIds and subnetIds are required
vpc:
securityGroupIds:
- securityGroupId1
subnetIds:
- subnetId1
- subnetId2
您引用的子网需要有到您的数据库配置到的子网的路由。它们可以与您的 RDS 实例或 EC2 在数据库中 运行 的子网中。
最后,您需要确保安全组允许 Lambda 安全组的正确端口上的出站流量,以及确保数据库(EC2 或 RDS)上的安全组允许来自Lambda SG 或您要将 Lambda 部署到正确端口 # 的子网的 CIDR/IP 范围。
挂起通常是请求未发送到数据库 - 如果您已经设置了部署在 VPC 中的 Lambda,那么您应该检查提到的路由和安全组。