将 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,那么您应该检查提到的路由和安全组。