【问题标题】:Create a database-service in AWS Lambda在 AWS Lambda 中创建数据库服务
【发布时间】:2020-07-02 15:36:34
【问题描述】:

我正在 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);
        }
}

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

如果有人以前遇到过这个问题并解决了它,谁能给我建议?

【问题讨论】:

  • 您如何管理部署?如果您使用的是 CloudFormation 或 Terraform 之类的东西,您可以使用它为您创建 DynamoDB 表,而不是依赖 Java 代码来执行此操作。
  • 我正在使用 Terraform 部署我的 Lambda 函数并与 api-gateway 集成。
  • @MarkB - 你能建议我一种方法,我可以依靠我的 java 代码而不是使用脚本来创建表吗?
  • 数据库服务是指DynamoDB还是RDS?您提到了架构更改。
  • @LLL - DynamoDB

标签: java amazon-web-services aws-lambda amazon-dynamodb terraform


【解决方案1】:

对我来说,最好的方法是使用 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 上浪费一点时间/金钱。

【讨论】:

    【解决方案2】:

    由于您是通过 Terraform 进行部署,因此正确的方法是发送至 have Terraform create the DynamoDB tables as well。您可以使用引用 aws_dynamodb_table 资源的 depends_on 属性在 Terraform 中配置 aws_lambda_function 资源,以便 Terraform 确保在 Lambda 函数之前创建表。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2015-04-20
        • 2018-09-11
        • 1970-01-01
        • 1970-01-01
        • 2020-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-30
        相关资源
        最近更新 更多