跳到主要内容

8.1 云配置

为云构建的应用程序通常需要适应在云环境中运行,以分布式方式读取和共享配置,并在必要时将配置外部化到环境中。

Micronaut 的环境概念默认为云平台感知,并尽最大努力检测底层活动环境。

然后,你可以使用 Requires 注解有条件地加载 Bean 定义

下表总结了环境接口中的常量,并提供了一个示例:

表 1.Micronaut 环境检测

常量描述Requires 示例环境名字
ANDROID应用程序作为 Android 应用程序运行@Requires(env = Environment.ANDROID)android
TEST应用程序在 JUnit 或 Spock 测试中运行@Requires(env = Environment.TEST)test
CLOUD应用程序在云环境中运行(适用于所有其他云平台类型)@Requires(env = Environment.CLOUD)cloud
AMAZON_EC2Amazon EC2 上运行@Requires(env = Environment.AMAZON_EC2)ec2
GOOGLE_COMPUTEGoogle Compute 上运行@Requires(env = Environment.GOOGLE_COMPUTE)gcp
KUBERNETESKubernetes 上运行@Requires(env = Environment.KUBERNETES)k8s
HEROKUHeroku 上运行@Requires(env = Environment.HEROKU)heroku
CLOUD_FOUNDRYCloud Foundry 上运行@Requires(env = Environment.CLOUD_FOUNDRY)pcf
AZUREMicrosoft Azure 上运行@Requires(env = Environment.AZURE)azure
IBMIBM Cloud 上运行@Requires(env = Environment.IBM)ibm
DIGITAL_OCEANDigital Ocean 上运行@Requires(env = Environment.DIGITAL_OCEAN)digitalocean
ORACLE_CLOUDOracle Cloud 上运行@Requires(env = Environment.ORACLE_CLOUD)oraclecloud

请注意,你可以有多个活动环境,例如在 AWS 的 Kubernetes 中运行时。

此外,使用上表中定义的常量值可以创建特定环境的配置文件。例如,如果创建了 src/main/resources/application-gcp.yml 文件,只有在 Google Compute 上运行时才会加载该文件。

提示

环境中的任何配置属性也可以通过环境变量来设置。例如,设置 CONSUL_CLIENT_HOST 环境变量可覆盖 ConsulConfiguration 中的 host 属性。

使用云实例元数据

当 Micronaut 检测到它在受支持的云平台上运行时,它就会在启动时填充 ComputeInstanceMetadata 接口。

提示

从 Micronaut 2.1.x 开始,这一逻辑取决于是否存在 Oracle Cloud、AWS 或 GCP 的相应核心云模块。

所有这些数据都会合并到正在运行的ServiceInstance的元数据属性中。

要访问应用程序实例的元数据,你可以使用 EmbeddedServerInstance 接口并调用 getMetadata(),它会返回一个元数据映射表。

如果通过客户端进行远程连接,一旦从LoadBalancer或 DiscoveryClient API 获取了ServiceInstance,就可以引用实例元数据。

提示

Netflix Ribbon 客户端负载平衡器可配置为使用元数据进行区域感知客户端负载平衡。参阅客户端负载平衡

要通过服务发现获取服务的元数据,可使用 LoadBalancerResolver 接口来解析 LoadBalancer 并通过标识符获取服务的引用:

获取服务实例的元数据

LoadBalancer loadBalancer = loadBalancerResolver.resolve("some-service");
Flux.from(
loadBalancer.select()
).subscribe((instance) ->
ConvertibleValues<String> metaData = instance.getMetadata();
...
);

EmbeddedServerInstance 可通过监听 ServiceReadyEvent 的事件监听器使用。使用 @EventListener 注解可以轻松地在你的 Bean 中监听事件。

要获取本地运行服务器的元数据,请使用 ServiceReadyEvent事件监听器

获取本地服务器的元数据

@EventListener
void onServiceStarted(ServiceReadyEvent event) {
ServiceInstance serviceInstance = event.getSource();
ConvertibleValues<String> metadata = serviceInstance.getMetadata();
}

8.1.1 分页式配置

正如你所看到的,Micronaut 拥有一个强大的系统,用于外部化配置并使其适应环境,其灵感来自 Grails 和 Spring Boot 中的类似方法。

但是,如果你想让多个微服务共享配置,该怎么办呢?Micronaut 包含用于分布式配置的 API。

ConfigurationClient 接口有一个 getPropertySources 方法,可用于从分布式源读取和解析配置。

getPropertySources 返回一个Publisher,该发布者发布零或多个 PropertySource 实例。

默认实现是 DefaultCompositeConfigurationClient,它将所有已注册的 ConfigurationClient Bean 合并为一个 Bean。

你可以实现自己的 ConfigurationClient 或使用 Micronaut 提供的实现。下面的章节将介绍。

8.1.2 HashiCorp Consul 支持

Consul 是由 HashiCorp 提供的一种流行的服务发现和分布式配置服务器。Micronaut 有一个本地 ConsulClient,它使用 Micronaut 对声明式 HTTP 客户端的支持。

启动 Consul

开始使用 Consul 的最快方法是通过 Docker:

  1. 使用 Docker 启动 Consul
docker run -p 8500:8500 consul

或者,你也可以安装并运行一个本地 Consul 实例


使用 Consul 启用分布式配置

提示

使用 CLI

如果使用 Micronaut CLI 创建项目,请提供 config-consul 特性,以便在项目中启用 Consul 的分布式配置:

$ mn create-app my-app --features config-consul

要启用分布式配置,请确保已启用 [bootstrap],并使用以下配置创建一个 src/main/resources/bootstrap.[yml/toml/properties] 文件:

micronaut.application.name=hello-world
micronaut.config-client.enabled=true
consul.client.defaultZone=${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}

启用分布式配置后,在 Consul 的键/值存储中存储要共享的配置。有多种方法可以做到这一点。


以键/值对形式存储配置

一种方法是直接在 Consul 中存储键和值。在这种情况下,默认情况下 Micronaut 会在 Consul /config 目录中查找配置。

提示

你可以通过设置 consul.client.config.path 来改变搜索路径。

/config 目录中,Micronaut 按优先顺序搜索下列目录中的值:

表 1.配置解析优先级

目录描述
/config/application所有应用程序共享配置
/config/application,prodprod 环境中所有应用程序共享的配置
/config/[APPLICATION_NAME]特定于应用程序的配置,例如 /config/hello-world
/config/[APPLICATION_NAME],prod活动环境的特定应用程序配置

APPLICATION_NAME 的值就是你在 bootstrap 配置文件中配置的 micronaut.application.name 的值。 要查看实际操作,请使用下面的 cURL 命令在 /config/application 目录中存储一个名为 foo.bar 的属性,其值为 myvalue

使用 cURL 写入值

curl -X PUT -d @- localhost:8500/v1/kv/config/application/foo.bar <<< myvalue

如果你现在定义了 @Value("${foo.bar}"),或调用 environment.getProperty(..) 将从 Consul 解析出 myvalue 值。


以 YAML、JSON 等格式存储配置

有些 Consul 用户喜欢用某种格式的 blob 来存储配置,比如 YAML。Micronaut 支持这种模式,并支持以 YAML、JSON 或 Java 属性格式存储配置。

提示

ConfigDiscoveryConfiguration 有许多配置选项,用于配置如何发现分布式配置。

你可以设置 consul.client.config.format 选项来配置读取属性的格式。

例如,配置 JSON 格式:

consul.client.config.format=JSON

现在将配置以 JSON 格式写入 Consul:

使用 cURL 编写 JSON

curl -X PUT  localhost:8500/v1/kv/config/application \
-d @- << EOF
{ "foo": { "bar": "myvalue" } }
EOF

将配置存储为文件引用

另一个流行的选项是 git2consul,它能将 Git 仓库的内容镜像到 Consul 的键/值存储。

你可以建立一个包含 application.ymlhello-world-test.json 等文件的 Git 仓库,这些文件的内容将被克隆到 Consul 中。

在这种情况下,Consul 中的每个键都代表一个带扩展名的文件,例如 /config/application.yml,你必须配置 FILE 格式:

consul.client.config.format=FILE

8.1.3 HashiCorp Vault 支持

Micronaut 与作为分布式配置源的 HashiCorp Vault 集成。

要启用分布式配置,请确保已启用 [bootstrap],并创建一个 src/main/resources/bootstrap.[yml/toml/properties]文件,配置如下:

与 HashiCorp Vault 集成

micronaut.application.name=hello-world
micronaut.config-client.enabled=true
vault.client.config.enabled=true

有关所有配置选项,参阅配置参考

Micronaut 使用配置的 micronaut.application.name 从 Vault 查找应用程序的属性源。

表 1.配置解析优先级

目录描述
/application所有应用程序共享配置
/[APPLICATION_NAME]特定应用配置
/application/[ENV_NAME]活动环境名称中所有应用程序共享的配置
/[APPLICATION_NAME]/[ENV_NAME]活动环境名称的特定应用程序配置

有关如何设置服务器的更多信息,参阅 HashiCorp Vault 文档

8.1.4 Spring Cloud 配置支持

自 1.1 版起,Micronaut 为那些尚未转向 Consul 等更完整的专用解决方案的用户提供了原生 Spring 云配置功能。

要启用分布式配置,请确保已启用 [bootstrap],并使用以下配置创建一个 src/main/resources/bootstrap.[yml/toml/properties] 文件:

与 Spring 云配置集成

micronaut.application.name=hello-world
micronaut.config-client.enabled=true
spring.cloud.config.enabled=true
spring.cloud.config.uri=http://localhost:8888/
spring.cloud.config.retry-attempts=4
spring.cloud.config.retry-delay=2s
  • retry-attempts 是可选项,用于指定重试次数。
  • retry-delay 是可选项,用于指定重试之间的延迟时间。

Micronaut 使用配置的 micronaut.application.name 从通过 spring.cloud.config.uri 配置的 Spring Cloud 配置服务器中查找应用程序的属性源。

有关如何设置服务器的更多信息,参阅 Spring Cloud 配置服务器文档

8.1.5 AWS 参数存储支持

Micronaut 支持通过 AWS 系统管理器参数存储共享配置。你需要配置以下依赖:

implementation("io.micronaut.aws:micronaut-aws-parameter-store")

要启用分布式配置,请确保已启用 bootstrap,并创建包含以下配置的 src/main/resources/bootstrap.yml 文件:

micronaut.application.name=hello-world
micronaut.config-client.enabled=true
aws.client.system-manager.parameterstore.enabled=true

有关所有配置选项,参阅配置参考

你可以从 AWS 控制台 → 系统管理器 → 参数存储配置共享属性。

Micronaut 使用层次结构读取配置值,并支持 StringStringListSecureString 类型。

你也可以通过在下划线 _ 后加上环境名称来创建特定环境的配置。例如,如果 micronaut.application.name 设置为 helloworld,那么在 helloworld_test 下指定的配置值将只应用于测试环境。

表 1.配置解析优先级

目录描述
/config/application所有应用程序共享配置
/config/[APPLICATION_NAME]特定于应用程序的配置,例如 /config/hello-world
/config/application_prodprod 环境中所有应用程序共享的配置
/config/[APPLICATION_NAME]_prod活动环境的特定应用程序配置

例如,如果在 AWS 参数存储中配置了配置名称 /config/application_test/server.url,则任何连接到该参数存储的应用程序都可以使用 server.url 检索该值。如果应用程序将 micronaut.application.name 配置为 myapp,则名称为 /config/myapp_test/server.url 的值会覆盖该应用程序的值。

树的每一层都可以由键=值对组成。对于多个键/值对,请将类型设为 StringList

对于特殊的安全信息,如密钥或密码,请使用 SecureString 类型。添加和检索值时将自动调用 KMS,并使用账户的默认密钥存储对其进行解密。如果你将配置设置为不使用安全字符串,它们将加密后返回给你,你必须手动解密它们。

8.1.6 Oracle Cloud Vault 支持

参阅 Oracle Cloud Vault 安全分布式配置文档。

8.1.7 Google Cloud 发布/订阅支持

参阅 Micronaut GCP Pub/Sub 文档。

8.1.8 Kubernetes 支持

参阅 Kubernetes 配置客户端 文档。

英文链接