繁体   English   中英

在 AWS Lambda 中创建数据库服务

[英]Create a database-service in AWS Lambda

我正在 AWS Lambda 服务上使用 java 和 spring-boot 开发 Web 应用程序。 我正在设计它以拥有一个数据库服务。 这将是 Entity(table) 和 JPARepositories 类的集合。 因此,如果我需要更改任何数据库架构,我只需要在此服务中进行更改。

将通过 API 网关公开的其他服务将使用此数据库服务作为 Lambda 层。

parent-project 
|
|---database-service
|
|---API-service1
|
|---API-service2
...

问题是我需要在部署任何 Lambda 服务之前创建表。 以便此 API-Services 可以使用它们。 解决此问题的一种方法是将数据库服务部署为 Lambda 函数并调用该函数,该函数将调用如下所示的方法来创建所有表。

@SpringBootApplication
public class DatabaseServiceApplication implements CommandLineRunner {

    private DynamoDBMapper dynamoDBMapper;

    private final AmazonDynamoDB amazonDynamoDB;

    public DatabaseServiceApplication(AmazonDynamoDB amazonDynamoDB) {
        this.amazonDynamoDB = amazonDynamoDB;
    }

    public static void main(String[] args) {
        SpringApplication.run(DatabaseServiceApplication.class, args);
    }

    @Override
        public void run(String... strings) {
            dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
            CreateTableRequest tableRequest = dynamoDBMapper
                    .generateCreateTableRequest(Association.class);
            tableRequest.setProvisionedThroughput(
                    new ProvisionedThroughput(1L, 1L));
            TableUtils.createTableIfNotExists(amazonDynamoDB, tableRequest);
        }
}

或者使用脚本来创建表。 我不确定哪个是更好的选择,或者有没有更好的选择。

任何人都可以建议我是否有人以前遇到过这个问题并解决了它?

对我来说,最好的方法是使用 Lambda 冷启动。 您的代码需要足够智能,不必关心数据库是否已经正确。 根据您显示的代码,我将按以下顺序执行某些操作:

public class LambdaExample implements RequestStreamHandler {

    // only called on cold start
    public LambdaExample() {
        dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
        CreateTableRequest tableRequest = dynamoDBMapper
                .generateCreateTableRequest(Association.class);
        tableRequest.setProvisionedThroughput(
                new ProvisionedThroughput(1L, 1L));
        TableUtils.createTableIfNotExists(amazonDynamoDB, tableRequest);
    }

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) {
        // handle request.  this lambda type requires reading the inputStream
        // yourself but use whatever you normally have here.
    }

如果您使用的是传统的关系数据库,则可以改用Flyway 它也知道数据库是否已经更新。

请注意,如果您有数千个 Lambda,它们都会调用它,从而减慢每个 Lambda 的冷启动速度。 这就是为什么@MarkB 建议将数据库创建外部化的过程,因为实际上只有启动的第一个 Lambda 才能做任何有用的事情。 之后,您会在每个新的 Lambda 上浪费一些时间/金钱。

由于您通过 Terraform 进行部署,那么正确的方法是让 Terraform 创建 DynamoDB 表 你会配置aws_lambda_function在Terraform与资源depends_on财产引用aws_dynamodb_table资源,使Terraform将确保该表是lambda函数之前创建。

你能回答下面的问题吗? 1) 您是否在 lambda 中部署您的 springboot 应用程序? 如果是,那听起来不是很好地使用 Springboot,Springboot 应用程序应该托管在 EC2/ECS 实例中才能启动并运行(24/7)。 将 Lambda 视为运行以处理简单任务的函数。 为此,您可以编写一个简单的 Java 应用程序,并将 jar 部署到 lambda 函数。

2) CloudFormation、TerraForm 等语言用于创建基础设施,通常先运行基础设施作业,然后再进行部署。

这是我为个人项目构建的 terraform 结构的链接。 https://github.com/saifmasadeh/terraform-project-structure

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM