通过


你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure 容器应用 中连接到 Spring 的托管配置服务器

Config Server for Spring 提供了集中位置来向多个应用程序提供配置数据。 本文介绍如何将托管在 Azure 容器应用 中的应用连接到 Java Config Server for Spring 实例。

适用于 Spring Java 组件的配置服务器使用GitHub存储库作为配置设置的源。 配置值通过组件和容器应用之间的绑定提供给容器应用。 当配置服务器中的值发生更改时,它们会自动流向应用程序,而无需重新编译或重新部署应用程序。

在本教程中,学习:

  • 为 Spring Java 组件创建配置服务器
  • 将 Config Server for Spring 绑定到容器应用
  • 在将配置服务器连接到应用程序前后观察配置值
  • 使用对称密钥加密和解密配置值

重要

本教程使用可能影响Azure帐单的服务。 如果你决定按部就班,请确保删除本文中特别推荐的资源,以避免意外计费。

先决条件

注意事项

在 Azure 容器应用 的 Config Server for Spring 中运行时,请注意以下详细信息:

说明
范围 Config Server for Spring 的运行环境与连接的容器应用相同。
缩放 为了保持单一事实来源,Spring 的 Config Server 无法有效扩展。 缩放属性 minReplicasmaxReplicas 都设置为 1
资源 Config Server for Spring 的容器资源分配是固定的,CPU 核心数为 0.5,内存大小为 1Gi。
定价 Config Server for Spring 的计费属于按使用量计费模式。 托管Java组件消耗的资源按活动/空闲费率计费。 可以删除不再使用的组件以停止计费。
绑定 容器应用通过绑定连接到 Config Server for Spring。 绑定将配置注入容器应用环境变量。 建立绑定后,容器应用可以从环境变量中读取配置值。

安装

在开始使用 Config Server for Spring 之前,首先需要创建所需的资源。

执行以下命令来创建资源组和容器应用环境。

  1. 创建变量来支持应用程序配置。 这些值是为了本课程的目的而向你提供的。

    export LOCATION=eastus
    export RESOURCE_GROUP=my-services-resource-group
    export ENVIRONMENT=my-environment
    export JAVA_COMPONENT_NAME=configserver
    export APP_NAME=my-config-client
    export IMAGE="mcr.microsoft.com/javacomponents/samples/sample-service-config-client:latest"
    export URI="https://github.com/Azure-Samples/azure-spring-cloud-config-java-aca.git"
    
    变量 说明
    LOCATION 创建容器应用和Java组件的Azure区域位置。
    ENVIRONMENT 演示应用程序的Azure 容器应用环境名称。
    RESOURCE_GROUP 演示应用程序的Azure资源组名称。
    JAVA_COMPONENT_NAME 为容器应用创建的Java组件的名称。 在这种情况下,请为 Spring Java 组件创建配置服务器。
    IMAGE 您的容器应用中使用的容器镜像。
    URI 可以将 URI 替换为 Git 存储库 URL(如果是专用的),请添加相关的身份验证配置,例如 spring.cloud.config.server.git.usernamespring.cloud.config.server.git.password
  2. 使用Azure CLI登录到Azure。

    az login
    
  3. 创建资源组。

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  4. 创建容器应用环境。

    az containerapp env create \
        --name $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION
    

此环境用于托管 Config Server for Spring Java 组件和容器应用。

为 Spring Java 组件创建配置服务器

有了容器应用环境后,可创建容器应用并将其绑定到 Config Server for Spring Java 组件。 绑定容器应用时,配置值会自动从 Config Server 组件同步到应用程序。

  1. 为 Spring Java 组件创建配置服务器。

    az containerapp env java-component config-server-for-spring create \
        --environment $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --name $JAVA_COMPONENT_NAME \
        --min-replicas 1 \
        --max-replicas 1 \
        --configuration spring.cloud.config.server.git.uri=$URI
    
  2. 更新 Spring Java 组件的配置服务器。

    az containerapp env java-component config-server-for-spring update \
        --environment $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --name $JAVA_COMPONENT_NAME \
        --min-replicas 2 \
        --max-replicas 2 \
        --configuration spring.cloud.config.server.git.uri=$URI spring.cloud.config.server.git.refresh-rate=60
    

    在这里,你将告诉组件在何处查找通过 uri 属性保存配置信息的存储库。 refresh-rate 属性告知容器应用检查 Git 存储库中的更改的频率。

将容器应用绑定到 Spring Java 组件的配置服务器

  1. 创建使用配置数据的容器应用。

    az containerapp create \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --environment $ENVIRONMENT \
        --image $IMAGE \
        --min-replicas 1 \
        --max-replicas 1 \
        --ingress external \
        --target-port 8080 \
        --query properties.configuration.ingress.fqdn
    

    此命令返回使用配置数据的容器应用的 URL。 将 URL 复制到文本编辑器,以便在下一步中使用。

    如果在浏览器中访问应用,则返回的 connectTimeout 值是 0 的默认值。

  2. 绑定到 Spring 的配置服务器。

    创建容器应用和 Config Server 后,将它们与 update 命令一起绑定到容器应用。

    az containerapp update \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --bind $JAVA_COMPONENT_NAME
    

    --bind $JAVA_COMPONENT_NAME 参数在容器应用和配置组件之间创建链接。

容器应用和 Config Server 组件绑定在一起后,配置更改会自动同步到容器应用。

再次访问应用的 URL 时,connectTimeout 的值现在为 10000。 此值来自 $URI 变量中最初设置为配置组件源的 Git 存储库。 具体而言,此值取自存储库的 `connectionTimeout` 属性,并位于 `application.yml` 文件中。

绑定请求将配置设置以环境变量的形式注入应用程序。 从配置服务器提取配置设置时,这些值现在可提供给应用程序代码使用。

在这种情况下,应用程序可使用以下环境变量:

SPRING_CLOUD_CONFIG_URI=http://[JAVA_COMPONENT_INTERNAL_FQDN]:80
SPRING_CLOUD_CONFIG_COMPONENT_URI=http://[JAVA_COMPONENT_INTERNAL_FQDN]:80
SPRING_CONFIG_IMPORT=optional:configserver:$SPRING_CLOUD_CONFIG_URI

如果要自定义自己的 SPRING_CONFIG_IMPORT,可以引用环境变量 SPRING_CLOUD_CONFIG_COMPONENT_URI - 例如,可以通过命令行参数(如 Java -Dspring.config.import=optional:configserver:${SPRING_CLOUD_CONFIG_COMPONENT_URI}?fail-fast=true)替代。

还可从应用程序中移除绑定。

(可选)将容器应用从 Spring Java 组件的配置服务器解除绑定

若要从容器应用中移除绑定,请使用 --unbind 选项。

az containerapp update \
    --name $APP_NAME \
    --unbind $JAVA_COMPONENT_NAME \
    --resource-group $RESOURCE_GROUP

再次访问应用的 URL 时,connectTimeout 的值变回 0

清理资源

本教程中创建的资源对Azure帐单产生影响。 如果不打算长期使用这些服务,请运行以下命令来删除本教程中创建的所有内容。

az group delete --resource-group $RESOURCE_GROUP

配置选项

az containerapp update命令使用--configuration参数控制 Config Server for Spring 的配置方式。 只要多个参数被空格分隔,就可以一次性使用它们。 有关详细信息,请参阅 Spring Cloud Config Server

下表列出了可用的不同 Git 后端配置值:

名称 说明
spring.cloud.config.server.git.uri
spring.cloud.config.server.git.repos.{repoName}.uri
远程存储库的 URI。
spring.cloud.config.server.git.username
spring.cloud.config.server.git.repos.{repoName}.username
使用远程存储库进行身份验证的用户名。
spring.cloud.config.server.git.password
spring.cloud.config.server.git.repos.{repoName}.password
使用远程存储库进行身份验证的密码。
spring.cloud.config.server.git.search-paths
spring.cloud.config.server.git.repos.{repoName}.search-paths
在本地工作副本中使用的搜索路径。 默认情况下,仅搜索根目录。
spring.cloud.config.server.git.force-pull
spring.cloud.config.server.git.repos.{repoName}.force-pull
用于指示存储库应强制拉取的标志。 如果为 true,则放弃任何本地更改并从远程存储库获取。
spring.cloud.config.server.git.default-label
spring.cloud.config.server.git.repos.{repoName}.default-label
用于 Git 的默认标签为 main。 如果未设置 spring.cloud.config.server.git.default-label ,并且名为 main 的分支不存在,则配置服务器默认会尝试检出名为 master 的分支。 若要禁用回退分支行为,可以将 spring.cloud.config.server.git.tryMasterBranch 设置为 false
spring.cloud.config.server.git.try-master-branch
spring.cloud.config.server.git.repos.{repoName}.try-master-branch
默认情况下,配置服务器将尝试签出名为 master 的分支。
spring.cloud.config.server.git.skip-ssl-validation
spring.cloud.config.server.git.repos.{repoName}.skip-ssl-validation
可以通过将 git.skipSslValidation 属性设置为 true 来禁用配置服务器对 Git 服务器的 TLS/SSL 证书的验证。
spring.cloud.config.server.git.clone-on-start
spring.cloud.config.server.git.repos.{repoName}.clone-on-start
用于指示应在启动时(而非按需)克隆存储库的标志。 通常会导致启动速度变慢,但第一个查询速度会变快。
spring.cloud.config.server.git.timeout
spring.cloud.config.server.git.repos.{repoName}.timeout
获取 HTTP 或 SSH 连接的超时(以秒为单位)(如果适用)。 默认的值为 5 秒。
spring.cloud.config.server.git.refresh-rate
spring.cloud.config.server.git.repos.{repoName}.refresh-rate
Config Server 从你的 Git 后端提取更新后的配置数据的频率。
spring.cloud.config.server.git.private-key
spring.cloud.config.server.git.repos.{repoName}.private-key
验证 SSH 私钥。 如果 ignore-local-ssh-settingstrue 且 Git URI 采用 SSH 格式,则必须设置。
spring.cloud.config.server.git.host-key
spring.cloud.config.server.git.repos.{repoName}.host-key
有效的 SSH 主机密钥。 如果还设置了 host-key-algorithm,则必须设置。
spring.cloud.config.server.git.host-key-algorithm
spring.cloud.config.server.git.repos.{repoName}.host-key-algorithm
ssh-dssssh-rsassh-ed25519ecdsa-sha2-nistp256ecdsa-sha2-nistp384ecdsa-sha2-nistp521 的其中一个。 如果还设置了 host-key,则必须设置。
spring.cloud.config.server.git.strict-host-key-checking
spring.cloud.config.server.git.repos.{repoName}.strict-host-key-checking
truefalse。 如果 false,则忽略主机密钥的错误。
spring.cloud.config.server.git.repos.{repoName} 远程存储库的 URI。
spring.cloud.config.server.git.repos.{repoName}.pattern 模式格式是一个使用逗号分隔并带有通配符的 {application}/{profile} 名称列表。 如果 {application}/{profile} 与任何模式不匹配,则它使用定义的默认 URI。

以下列表描述了常见配置:

  • 日志记录相关配置:

    • logging.level.*
    • logging.group.*
    • 应禁止使用 logging.* 命名空间下的任何其他配置,例如,应禁止使用 logging.file 写入日志文件。
  • spring.cloud.config.server.overrides

    • 要无条件地发送到所有客户端的属性源的额外映射。
  • spring.cloud.config.override-none

    • 可以通过在远程存储库中设置 spring.cloud.config.override-none=true 标志(默认值为 false)来更改客户端中所有替代的优先级,使它们更像是默认值,让应用程序在环境变量或系统属性中提供自己的值。
  • spring.cloud.config.allow-override

    • 如果启用配置起始引导,则可以允许客户端应用程序覆盖来自配置服务器的配置。 通过在来自配置服务器的应用程序配置中放置两个属性来完成覆盖。
  • spring.cloud.config.server.health.*

    • 可以将运行状况指示器配置为检查更多应用程序以及自定义配置文件和自定义标签。
  • spring.cloud.config.server.accept-empty

    • 如果找不到应用程序,则可以将 spring.cloud.config.server.accept-empty 设置为 false 来让服务器返回 HTTP 404 状态。 此标志默认设置为 true
  • 加密和解密(对称):

    • encrypt.key
      • 使用对称密钥时很方便,因为它是一个待配置的属性值。
    • spring.cloud.config.server.encrypt.enabled
      • 将此属性设置为 false 以禁用服务器端解密。

刷新​​

使用属性的服务需要在更改发生之前知道它。 Config Server for Spring 的默认通知方法涉及手动触发刷新事件,例如通过调用https://<YOUR_CONFIG_CLIENT_HOST_NAME>/actuator/refresh刷新,但如果有许多应用实例,这就可能不可行。

可以改为让配置客户端根据刷新间隔来轮询更改,从而自动刷新 Config Server 中的值。 使用以下步骤自动刷新 Config Server 中的值:

  1. 注册计划任务以按给定的间隔刷新上下文,如以下示例所示:

    @Configuration
    @AutoConfigureAfter({RefreshAutoConfiguration.class, RefreshEndpointAutoConfiguration.class})
    @EnableScheduling
    public class ConfigClientAutoRefreshConfiguration implements SchedulingConfigurer {
        @Value("${spring.cloud.config.refresh-interval:60}")
        private long refreshInterval;
        @Value("${spring.cloud.config.auto-refresh:false}")
        private boolean autoRefresh;
        private final RefreshEndpoint refreshEndpoint;
        public ConfigClientAutoRefreshConfiguration(RefreshEndpoint refreshEndpoint) {
            this.refreshEndpoint = refreshEndpoint;
        }
        @Override
        public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
            if (autoRefresh) {
                // set minimal refresh interval to 5 seconds
                refreshInterval = Math.max(refreshInterval, 5);
                scheduledTaskRegistrar.addFixedRateTask(refreshEndpoint::refresh,  Duration.ofSeconds(refreshInterval));
            }
        }
    }
    
  2. 在 application.yml 文件中启用 autorefresh 并设置适当的刷新间隔。 在以下示例中,客户端每隔 60 秒钟轮询一次配置更改,这是可为刷新间隔设置的最小值。

    默认情况下,autorefresh 设置为 falserefresh-interval 设置为 60 秒。

    spring:
        cloud:
            config:
            auto-refresh: true
            refresh-interval: 60
    management:
        endpoints:
            web:
            exposure:
                include:
                - refresh
    
  3. 在代码中添加 @RefreshScope。 在以下示例中,变量 connectTimeout 每隔 60 秒钟自动刷新一次:

    @RestController
    @RefreshScope
    public class HelloController {
        @Value("${timeout:4000}")
        private String connectTimeout;
    }
    

使用对称密钥进行加密和解密

服务器端解密

默认启用服务器端加密。 使用以下步骤在应用程序中启用解密:

  1. 在你的 Git 存储库中的 .properties 文件中添加加密属性。

    文件应与下面的示例类似:

    message={cipher}f43e3df3862ab196a4b367624a7d9b581e1c543610da353fbdd2477d60fb282f
    
  2. 更新 Spring Java 组件的配置服务器,以使用具有加密属性并设置加密密钥的 Git 存储库。

    在运行以下命令之前,请将 <> 括起来的占位符替换为你的值。

    az containerapp env java-component config-server-for-spring update \
        --environment <ENVIRONMENT_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --name <JAVA_COMPONENT_NAME> \
        --configuration spring.cloud.config.server.git.uri=<URI> encrypt.key=randomKey
    

客户端解密

可以按照以下步骤使用属性的客户端解密:

  1. 在你的 Git 存储库中的 .properties 文件中添加加密属性。

  2. 更新 Config Server for Spring Java 组件,以使用具有加密属性并禁用服务器端解密的 Git 存储库。

    在运行以下命令之前,请将 <> 括起来的占位符替换为你的值。

    az containerapp env java-component config-server-for-spring update \
        --environment <ENVIRONMENT_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --name <JAVA_COMPONENT_NAME> \
        --configuration spring.cloud.config.server.git.uri=<URI> spring.cloud.config.server.encrypt.enabled=false
    
  3. 在你的客户端应用中,将解密密钥 ENCRYPT_KEY=randomKey 添加为环境变量。

    或者,如果在 spring-cloud-starter-bootstrap 上包含 classpath,或将 spring.cloud.bootstrap.enabled=true 设置为系统属性,则在 encrypt.key 中设置 bootstrap.properties

    在运行以下命令之前,请将 <> 括起来的占位符替换为你的值。

    az containerapp update \
        --name <APP_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --set-env-vars "ENCRYPT_KEY=randomKey"
    
    encrypt:
      key: somerandomkey