阅读(1556) (0)

Micronaut 云配置

2023-02-23 13:40:49 更新

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

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

然后,您可以使用 Requires 注释有条件地加载 bean 定义。

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

表 1. Micronaut 环境检测
常量 描述 需要示例 环境名称

ANDROID

该应用程序作为 Android 应用程序运行

@Requires(env = Environment.ANDROID)

android

TEST

应用程序在 JUnit 或 Spock 测试中运行

@Requires(env = Environment.TEST)

test

CLOUD

该应用程序在云环境中运行(适用于所有其他云平台类型)

@Requires(env = Environment.CLOUD)

cloud

AMAZON_EC2

在亚马逊 EC2 上运行

@Requires(env = Environment.AMAZON_EC2)

ec2

GOOGLE_COMPUTE

在谷歌 Compute 上运行

@Requires(env = Environment.GOOGLE_COMPUTE)

gcp

KUBERNETES

在 Kubernetes 上运行

@Requires(env = Environment.KUBERNETES)

k8s

HEROKU

在 Heroku 上运行

@Requires(env = Environment.HEROKU)

heroku

CLOUD_FOUNDRY

在 Cloud Foundry 上运行

@Requires(env = Environment.CLOUD_FOUNDRY)

pcf

AZURE

在微软 Azure 上运行

@Requires(env = Environment.AZURE)

azure

IBM

在 IBM Cloud 上运行

@Requires(env = Environment.IBM)

ibm

DIGITAL_OCEAN

在 Digital Ocean 上运行

@Requires(env = Environment.DIGITAL_OCEAN)

digitalocean

ORACLE_CLOUD

在 Oracle Cloud 上运行

@Requires(env = Environment.ORACLE_CLOUD)

oraclecloud

请注意,您可以激活多个环境,例如在 AWS 上的 Kubernetes 中运行时。

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

Environment 中的任何配置属性也可以通过环境变量进行设置。例如,设置 CONSUL_CLIENT_HOST 环境变量会覆盖 ConsulConfiguration 中的主机属性。

使用云实例元数据

当 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:

获取本地服务器的元数据

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

分布式配置

如您所见,Micronaut 具有一个健壮的系统,用于外部化和调整配置以适应受 Grails 和 Spring Boot 中类似方法启发的环境。

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

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

getPropertySources 返回发出零个或多个 PropertySource 实例的 Publisher。

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

您可以实现自己的 ConfigurationClient 或使用 Micronaut 提供的实现。以下部分涵盖了这些内容。

HashiCorp 领事支持

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

启动领事

开始使用 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] 文件:

 Properties Yaml  Toml  Groovy  Hocon  JSON 
micronaut.application.name=hello-world
micronaut.config-client.enabled=true
consul.client.defaultZone=${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}
micronaut:
  application:
    name: hello-world
  config-client:
    enabled: true
consul:
  client:
    defaultZone: "${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}"
[micronaut]
  [micronaut.application]
    name="hello-world"
  [micronaut.config-client]
    enabled=true
[consul]
  [consul.client]
    defaultZone="${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}"
micronaut {
  application {
    name = "hello-world"
  }
  configClient {
    enabled = true
  }
}
consul {
  client {
    defaultZone = "${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}"
  }
}
{
  micronaut {
    application {
      name = "hello-world"
    }
    config-client {
      enabled = true
    }
  }
  consul {
    client {
      defaultZone = "${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}"
    }
  }
}
{
  "micronaut": {
    "application": {
      "name": "hello-world"
    },
    "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,prod

prod 环境的所有应用程序共享的配置

/config/[APPLICATION_NAME]

特定于应用程序的配置,示例 /config/hello-world

/config/[APPLICATION_NAME],prod

活动环境的特定于应用程序的配置

APPLICATION_NAME 的值是您在引导程序配置文件中配置的任何 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(..) 值 myvalue 将从 Consul 解析。

在 YAML、JSON 等中存储配置

一些 Consul 用户更喜欢将配置存储在特定格式的 blob 中,例如 YAML。 Micronaut 支持这种模式,并支持以 YAML、JSON 或 Java 属性格式存储配置。

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

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

例如,要配置 JSON:

 Properties Yaml  Toml  Groovy  Hocon  JSON 
consul.client.config.format=JSON
consul:
  client:
    config:
      format: JSON
[consul]
  [consul.client]
    [consul.client.config]
      format="JSON"
consul {
  client {
    config {
      format = "JSON"
    }
  }
}
{
  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.yml、hello-world-test.json 等文件的 Git 存储库,这些文件的内容将被克隆到 Consul。

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

 Properties Yaml  Toml  Groovy  Hocon  JSON 
consul.client.config.format=FILE
consul:
  client:
    config:
      format: FILE
[consul]
  [consul.client]
    [consul.client.config]
      format="FILE"
consul {
  client {
    config {
      format = "FILE"
    }
  }
}
{
  consul {
    client {
      config {
        format = "FILE"
      }
    }
  }
}
{
  "consul": {
    "client": {
      "config": {
        "format": "FILE"
      }
    }
  }
}

HashiCorp 金库支持

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

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

与 HashiCorp Vault 集成

 Properties Yaml  Toml  Groovy  Hocon  JSON 
micronaut.application.name=hello-world
micronaut.config-client.enabled=true
vault.client.config.enabled=true
micronaut:
  application:
    name: hello-world
  config-client:
    enabled: true

vault:
  client:
    config:
      enabled: true
[micronaut]
  [micronaut.application]
    name="hello-world"
  [micronaut.config-client]
    enabled=true
[vault]
  [vault.client]
    [vault.client.config]
      enabled=true
micronaut {
  application {
    name = "hello-world"
  }
  configClient {
    enabled = true
  }
}
vault {
  client {
    config {
      enabled = true
    }
  }
}
{
  micronaut {
    application {
      name = "hello-world"
    }
    config-client {
      enabled = true
    }
  }
  vault {
    client {
      config {
        enabled = true
      }
    }
  }
}
{
  "micronaut": {
    "application": {
      "name": "hello-world"
    },
    "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 的文档。

Spring Cloud 配置支持

从 1.1 开始,Micronaut 为那些没有切换到专用的更完整的解决方案(如 Consul)的人提供了原生的 Spring Cloud 配置。

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

与 Spring Cloud 配置集成

 Properties Yaml  Toml  Groovy  Hocon  JSON
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
micronaut:
  application:
    name: hello-world
  config-client:
    enabled: true
spring:
  cloud:
    config:
      enabled: true
      uri: http://localhost:8888/
      retry-attempts: 4
      retry-delay: 2s
[micronaut]
  [micronaut.application]
    name="hello-world"
  [micronaut.config-client]
    enabled=true
[spring]
  [spring.cloud]
    [spring.cloud.config]
      enabled=true
      uri="http://localhost:8888/"
      retry-attempts=4
      retry-delay="2s"
micronaut {
  application {
    name = "hello-world"
  }
  configClient {
    enabled = true
  }
}
spring {
  cloud {
    config {
      enabled = true
      uri = "http://localhost:8888/"
      retryAttempts = 4
      retryDelay = "2s"
    }
  }
}
{
  micronaut {
    application {
      name = "hello-world"
    }
    config-client {
      enabled = true
    }
  }
  spring {
    cloud {
      config {
        enabled = true
        uri = "http://localhost:8888/"
        retry-attempts = 4
        retry-delay = "2s"
      }
    }
  }
}
{
  "micronaut": {
    "application": {
      "name": "hello-world"
    },
    "config-client": {
      "enabled": true
    }
  },
  "spring": {
    "cloud": {
      "config": {
        "enabled": true,
        "uri": "http://localhost:8888/",
        "retry-attempts": 4,
        "retry-delay": "2s"
      }
    }
  }
}
  • retry-attempts 可选,指定重试次数

  • retry-delay 是可选的,指定重试之间的延迟

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

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

AWS 参数存储支持

Micronaut 支持通过 AWS System Manager Parameter Store 共享配置。您需要配置以下依赖项:

 Gradle Maven 
implementation("io.micronaut.aws:micronaut-aws-parameter-store")
<dependency>
    <groupId>io.micronaut.aws</groupId>
    <artifactId>micronaut-aws-parameter-store</artifactId>
</dependency>

要启用分布式配置,请确保已启用引导程序并使用以下配置创建一个 src/main/resources/bootstrap.yml 文件:

 Properties Yaml  Toml  Groovy  Hocon  JSON 
micronaut.application.name=hello-world
micronaut.config-client.enabled=true
aws.client.system-manager.parameterstore.enabled=true
micronaut:
  application:
    name: hello-world
  config-client:
    enabled: true
aws:
  client:
    system-manager:
      parameterstore:
        enabled: true
[micronaut]
  [micronaut.application]
    name="hello-world"
  [micronaut.config-client]
    enabled=true
[aws]
  [aws.client]
    [aws.client.system-manager]
      [aws.client.system-manager.parameterstore]
        enabled=true
micronaut {
  application {
    name = "hello-world"
  }
  configClient {
    enabled = true
  }
}
aws {
  client {
    systemManager {
      parameterstore {
        enabled = true
      }
    }
  }
}
{
  micronaut {
    application {
      name = "hello-world"
    }
    config-client {
      enabled = true
    }
  }
  aws {
    client {
      system-manager {
        parameterstore {
          enabled = true
        }
      }
    }
  }
}
{
  "micronaut": {
    "application": {
      "name": "hello-world"
    },
    "config-client": {
      "enabled": true
    }
  },
  "aws": {
    "client": {
      "system-manager": {
        "parameterstore": {
          "enabled": true
        }
      }
    }
  }
}

查看所有配置选项的配置参考。

您可以从 AWS 控制台 → 系统管理器 → Parameter Store 配置共享属性。

Micronaut 使用层次结构来读取配置值,并支持 String、StringList 和 SecureString 类型。

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

表 1. 配置解析优先级
目录 描述

/config/application

所有应用程序共享的配置

/config/[APPLICATION_NAME]

特定于应用程序的配置,示例 /config/hello-world

/config/application_prod

prod 环境的所有应用程序共享的配置

/config/[APPLICATION_NAME]_prod

活动环境的特定于应用程序的配置

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

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

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

Oracle Cloud Vault 支持

请参阅使用 Oracle Cloud Vault 文档的安全分布式配置。

谷歌云发布/订阅支持

请参阅 Micronaut GCP Pub/Sub 文档。

Kubernetes 支持

请参阅 Kubernetes 配置客户端文档。