1. 概述

Netflix Archaius 提供了丰富的库和功能,用于连接多种数据源。

在本教程中,我们将学习如何从以下几种方式获取配置:

  • ✅ 使用 JDBC API 连接数据库
  • ✅ 从 DynamoDB 实例中读取配置
  • ✅ 配置 Zookeeper 作为动态分布式配置中心

如果你对 Netflix Archaius 还不熟悉,可以先阅读 这篇文章

2. 使用 Netflix Archaius 结合 JDBC 连接数据库

正如在入门教程中所提到的,如果希望 Archaius 来管理配置,我们需要创建一个 Apache 的 AbstractConfiguration Bean。

Spring Cloud Bridge 会自动捕获该 Bean,并将其添加到 Archaius 的 Composite Configuration 栈中。

2.1. 依赖项

使用 JDBC 连接数据库所需的全部功能都包含在核心库中,因此除了入门教程中提到的依赖外,无需额外引入:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-archaius</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix</artifactId>
            <version>2.0.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

你可以访问 Maven Central 确认是否使用的是最新的 starter library 版本。

2.2. 如何创建配置 Bean

在这种情况下,我们需要通过 JDBCConfigurationSource 实例来创建 AbstractConfiguration Bean。

为了指定如何从数据库中读取配置值,我们需要提供:

  • 一个 javax.sql.DataSource 对象
  • 一条 SQL 查询语句,至少返回两个字段:key 和 value
  • 明确指出 key 和 value 所在的列名

下面是创建这个 Bean 的示例代码:

@Autowired
DataSource dataSource;

@Bean
public AbstractConfiguration addApplicationPropertiesSource() {
    PolledConfigurationSource source =
      new JDBCConfigurationSource(dataSource,
        "select distinct key, value from properties",
        "key",
        "value");
    return new DynamicConfiguration(source, new FixedDelayPollingScheduler());
}

2.3. 实战测试

为了保持简单又能运行,我们使用 H2 内存数据库并插入一些初始数据进行演示。

首先添加必要的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.0.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.197</version>
    <scope>runtime</scope>
</dependency>

⚠️ 注意:可以在 Maven Central 上查看 h2spring-boot-starter-data-jpa 的最新版本。

接着定义 JPA 实体类来存储属性:

@Entity
public class Properties {
    @Id
    private String key;
    private String value;
}

然后在资源目录下创建 data.sql 文件初始化数据:

insert into properties
values('baeldung.archaius.properties.one', 'one FROM:jdbc_source');

最后创建一个接口用于获取 Archaius 管理的属性值:

@RestController
public class ConfigPropertiesController {

    private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory
      .getInstance()
      .getStringProperty("baeldung.archaius.properties.one", "not found!");

    @GetMapping("/properties-from-dynamic")
    public Map<String, String> getPropertiesFromDynamic() {
        Map<String, String> properties = new HashMap<>();
        properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get());
        return properties;
    }
}

当数据库中的配置发生变化时,Archaius 会在运行时自动检测并更新值。

这个接口也可以在后续的例子中复用。

3. 使用 DynamoDB 作为配置源

与上一节类似,我们将创建一个完整的项目,深入理解 Archaius 如何使用 DynamoDB 作为配置源。

3.1. 依赖项

pom.xml 中添加如下依赖:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-dynamodb</artifactId>
    <version>1.11.414</version>
</dependency>
<dependency>
    <groupId>com.github.derjust</groupId>
    <artifactId>spring-data-dynamodb</artifactId>
    <version>5.0.3</version>
</dependency>
<dependency>
    <groupId>com.netflix.archaius</groupId>
    <artifactId>archaius-aws</artifactId>
    <version>0.7.6</version>
</dependency>

建议查阅 Maven Central 获取最新版本。对于 archaius-aws,推荐使用 Spring Cloud Netflix 库支持的版本

  • aws-java-sdk-dynamodb: 用于连接 DynamoDB 数据库
  • spring-data-dynamodb: 用于设置 DynamoDB Repository
  • archaius-aws: 用于创建 AbstractConfiguration

3.2. 使用 DynamoDB 作为配置源

这次我们使用 DynamoDbConfigurationSource 来创建 AbstractConfiguration

@Autowired
AmazonDynamoDB amazonDynamoDb;

@Bean
public AbstractConfiguration addApplicationPropertiesSource() {
    PolledConfigurationSource source = new DynamoDbConfigurationSource(amazonDynamoDb);
    return new DynamicConfiguration(
      source, new FixedDelayPollingScheduler());
}

默认情况下,Archaius 会查找名为 archaiusProperties 的表,其中包含 keyvalue 字段。

如果需要自定义表名或字段名,可以通过系统属性进行覆盖:

  • com.netflix.config.dynamo.tableName
  • com.netflix.config.dynamo.keyAttributeName
  • com.netflix.config.dynamo.valueAttributeName

3.3. 创建完整示例

按照 DynamoDB 指南,我们先安装本地 DynamoDB 实例以方便测试。

然后创建实体类映射 DynamoDB 表结构:

@DynamoDBTable(tableName = "archaiusProperties")
public class ArchaiusProperties {

    @DynamoDBHashKey
    @DynamoDBAttribute
    private String key;

    @DynamoDBAttribute
    private String value;

    // ...getters and setters...
}

定义 Repository:

public interface ArchaiusPropertiesRepository extends CrudRepository<ArchaiusProperties, String> {}

初始化表结构并插入数据:

@Autowired
private ArchaiusPropertiesRepository repository;

@Autowired
AmazonDynamoDB amazonDynamoDb;

private void initDatabase() {
    DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDb);
    CreateTableRequest tableRequest = mapper
      .generateCreateTableRequest(ArchaiusProperties.class);
    tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
    TableUtils.createTableIfNotExists(amazonDynamoDb, tableRequest);

    ArchaiusProperties property = new ArchaiusProperties("baeldung.archaius.properties.one", "one FROM:dynamoDB");
    repository.save(property);
}

此方法可在创建 DynamoDbConfigurationSource 前调用。

现在可以启动应用进行测试。

4. 配置 Zookeeper 动态分布式配置

如我们在 Zookeeper 入门文章 中所见,Zookeeper 的一大优势是可作为分布式配置存储中心。

结合 Archaius 后,就能实现灵活且可扩展的配置管理方案。

4.1. 依赖项

参考 Spring Cloud 官方文档 安装稳定版 Apache Zookeeper。

我们只需要部分功能,因此可以使用 spring-cloud-starter-zookeeper-config 依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-config</artifactId>
    <version>2.0.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.13</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

⚠️ 避免使用 Zookeeper 的 beta 版本。

4.2. Spring Cloud 自动配置

正如官方文档所述,只要引入 spring-cloud-starter-zookeeper-config 依赖,即可自动配置 Zookeeper 属性源。

默认情况下,只会自动配置一个源,它会在 /config/application 节点下查找属性。这个节点适用于多个应用共享的配置。

如果我们设置了 spring.application.name 属性,则还会自动配置另一个源,查找 /config/<app_name> 下的属性。

每个子节点的名称即为属性 key,节点内容即为属性 value。

幸运的是,Spring Cloud 会将这些属性源添加到上下文中,Archaius 也会自动管理它们,无需手动创建 AbstractConfiguration

4.3. 准备初始数据

我们还需要一个本地 Zookeeper 服务器来存储配置节点。可以参考 Apache 官方指南 安装单机模式服务器(默认端口 2181)。

使用 Apache Curator 客户端 创建初始数据:

@Component
public class ZookeeperConfigsInitializer {

    @Autowired
    CuratorFramework client;

    @EventListener
    public void appReady(ApplicationReadyEvent event) throws Exception {
        createBaseNodes();
        if (client.checkExists().forPath("/config/application/baeldung.archaius.properties.one") == null) {
            client.create()
              .forPath("/config/application/baeldung.archaius.properties.one",
              "one FROM:zookeeper".getBytes());
        } else {
            client.setData()
              .forPath("/config/application/baeldung.archaius.properties.one",
              "one FROM:zookeeper".getBytes());
        }
    }

    private void createBaseNodes() throws Exception {
        if (client.checkExists().forPath("/config") == null) {
            client.create().forPath("/config");
        }
        if (client.checkExists().forPath("/config/application") == null) {
            client.create().forPath("/config/application");
        }
    }
}

可通过日志查看 Netflix Archaius 是否在配置变更后刷新了属性值。

5. 总结

本文详细介绍了如何使用 Netflix Archaius 设置高级配置源。除了上述三种方式,它还支持其他多种数据源,如 Etcd、Typesafe、AWS S3 文件以及 JClouds。

一如既往,所有示例代码都可以在 GitHub 仓库 中找到。


原始标题:Netflix Archaius with Various Database Configurations

« 上一篇: Protonpack 介绍
» 下一篇: ScribeJava 使用指南