摘要: 本文介绍如何使用 sping-data-dynamodb 实现不同的 Profile 创建带有不同前缀的 table。
需求介绍
需求很简单,因为我们知道每个帐户中 DynamoDB 在每个 Region 都只有一个节点,也就是说当我们确定了 Region ,无论我们需要在该 Region 上部署多少个应用,其最终都是连接到一个 DynamoDB 上,不同的是,需要用 Table 来隔离不同的应用。Table 在 DynamoDB 中有点类似于 MySQL 中的 Database。
所以在这种前提上我们就有一个场景需要考虑:我们需要针对同一个应用搭建不同的版本,比如测试版本和线上版本,这时候就会存在一个问题:Table 的名字一样,DynamoDB 无法创建两个名字一样的表。
当然简单粗暴的解决方法是直接选用不同的 Region,但是这样管理起来很麻烦,同时 EC2 的选择变得困难,经过测试跨 Region 访问 DynamoDB 不如同一个 Region 速度快。
对于 DynamoDB 来说,该问题的最佳的解决方法就是:Table Name 增加前缀来标识同一个应用的不同的环境。
比如我们有一个表: User 表,那么最后我们部署后的两个表可以为:
- User: default 表名用于线上版本
- qaUser: 加 `qa` 前缀,用于 QA 版本
下面我们介绍如何使用 sping-data-dynamodb
配置 Spring 的 Profile 来实现
原理
基本文档参考 :https://github.com/derjust/spring-data-dynamodb/wiki/Alter-table-name-during-runtime
默认 Table Name 是静态字符串,定义在注解上:
1 | "someEntityTableName") (tableName = |
但是 AWS SDK DynamoDBMapperConfig
提供了更改表名的能力:
1 | /** |
其中的 TableNameOverride
就提供了更改前缀的方法
1 | /** |
所以我们只需要在不同的 Profile 的 Spring Configuration中配置不同的前缀就可以了。
代码实践
我们假设我们已经有了一个 dev
的 profile,这个 dev
profile 使用默认的表名,然后我们需要创建一个 dev2
的 profile,表名前缀为 dev2
,他们都连接到同一个本地的 DynamoDB 节点: localhost:8000
dev2 Profile yaml:
1 | amazon: |
DynamoDBDev2Configuration.java
1 |
|
这里我们要注意两个问题:
- 原文档中在
EnableDynamoDBRepositories
注解中加入了dynamoDBMapperConfigRef = "dynamoDBMapperConfig"
,但是经过测试这个属性会导致启动失败,原因是无法创建 Repository。所以删除了这个属性,使用默认值。 DynamoDBMapperConfig(DynamoDBMapperConfig.DEFAULT, builder.build())
is deprecated,虽然是弃用,但是这里我们希望基于DynamoDBMapperConfig.DEFAULT
做一些修改,目前没有提供类似的功能,因为其中 Builder 中有一个merge
方法,但是该方法是 private,而这个弃用的构造函数正是依靠这个 private 的merge
实现了。貌似 AWS 推荐完全通过builder
自己构建。 p.s. 建议增加一个toBuilder
的方法或者一个构造DynamoDBMapperConfig.DEFAULT
builder 的方法。