美妙的 GCP:使用 Spring Cloud GCP Runtime Config 进行运行时配置 (5/8)

工程 | Josh Long | 2018 年 9 月 3 日 | ...

嗨,Spring 粉丝们!在这个简短的 8 部分系列中,我们将了解 Google Cloud Platform 的 Spring Cloud 集成,称为 Spring Cloud GCP。 Spring Cloud GCP 代表了 Google 和 Pivotal 之间的共同努力,旨在为在使用 Google Cloud Platform 时提供 Spring Cloud 开发人员的一流体验。Pivotal Cloud Foundry 用户将享受更加 轻松与 GCP 服务代理集成。我编写了这些部分,并参考了 Google Cloud 开发者布道师以及我的朋友 Ray Tsang 的意见。您还可以在我们的 Google Next 2018 会议中了解 Spring Cloud GCP 的演练,Bootiful Google Cloud Platform。谢谢,伙计!与往常一样,如果您有任何反馈,我很乐意听取

本系列共有八篇文章。它们都在这里

](https://springframework.org.cn/blog/2018/09/06/bootiful-gcp-supporting-observability-with-spring-cloud-gcp-stackdriver-trace-6-8)

  • [Bootiful GCP:使用 Spring Cloud GCP 连接到其他 GCP 服务 (7/8)

](https://springframework.org.cn/blog/2018/09/10/bootiful-gcp-use-spring-cloud-gcp-to-connect-to-other-gcp-services-7-8)

到目前为止,我们已经查看了一些简单的示例,除了最简单的配置之外,所有示例都使用了配置。在有配置的地方,我们在 application.properties 中指定了它。这种方法有效,但存在局限性。中心化(使单个配置值可供许多其他客户端访问)、安全性(安全地存储机密)、实时重新配置以及审核和日志记录怎么样?还有许多其他解决方案可以解决这些用例中的一些或所有用例,包括 Apache Zookeeper、HashiCorp Consul、HashiCorp Vault(专门用于机密管理)以及当然还有 Spring Cloud Config Server。所有这些都是不错的选择,但您最好有一个扩展和保护这些基础设施部分的方案。GCP 提供了一种替代方案,即 Google Cloud RuntimeConfig,您可以使用它而无需更改现有代码,这要归功于 Spring 抽象的功能。

让我们看看如何建立配置值,然后从我们的应用程序中引用该值。我们还将了解如何稍后更新该配置,而无需重新启动应用程序。

首先,我们需要启用此 API。

gcloud services enable runtimeconfig.googleapis.com

让我们考虑一下我们希望如何使用此配置。我们可能有一些在本地机器上运行应用程序时有意义的配置值。我们可以从内置的 application.propertiesapplication.yaml 中获取的值。这些是应用于应用程序的默认值。将有一些值仅在生产环境中可见 - 定位器、凭据等 - 这些值对于生产环境是唯一的。例如,在 cloud 配置文件下运行时,这些值可能可见。我们将从 Google Cloud Runtime Config 中获取这些值(在 cloud 配置文件下运行时)。这样,我们可以有选择地覆盖重要值。

我们必须首先创建一个运行时配置,然后向该配置添加一个变量值。

gcloud beta runtime-config configs create reservations_cloud

然后,在刚刚创建的运行时配置中注册一个变量(greeting)及其值(Hello GCP)。

gcloud beta runtime-config configs variables set greeting  "Hello GCP"  --config-name reservations_cloud

我们可以像这样枚举给定配置集的所有配置

gcloud beta runtime-config configs variables list --config-name=reservations_cloud

Spring Cloud GCP 需要在大多数 Spring 应用程序运行之前执行其工作,因为它是一个属性源,将值馈送到其他配置中。因此,它执行其工作所需的任何配置都必须比通常在 application.properties 等文件中配置的配置更早地访问。在 Spring Cloud 中,此类配置通常位于 bootstrap.properties 中。让我们在本地机器上运行时禁用 Spring Cloud GCP Runtime Config,并且没有任何特定的 Spring 配置文件处于活动状态。

src/main/resources/bootstrap.properties。

spring.cloud.gcp.config.enabled=false
spring.cloud.gcp.config.credentials.location=${spring.cloud.gcp.credentials.location}

当我们在生产环境中(例如在 Cloud Foundry 中)运行时,我们将希望激活 cloud 配置文件,此时 Spring Cloud GCP Runtime Config 客户端将启动并从 GCP 获取配置。Spring Boot 非常聪明,它会除了默认配置之外,还会加载任何特定于配置文件的配置。您只需将配置文件后缀为 -${YOUR_PROFILE}:例如:application-foo.propertiesbootstrap-bar.yml 分别用于 Spring 配置文件 foobar。让我们为 cloud 配置文件处于活动状态时配置 Spring Cloud GCP。

src/main/resources/bootstrap-cloud.properties。

spring.cloud.gcp.config.enabled=true
spring.cloud.gcp.config.name=reservations
spring.cloud.gcp.config.profile=cloud

注意

${spring.cloud.gcp.config.name}_${spring.cloud.gcp.config.profile} 的组合形成了 reservations_cloud,这是我们刚刚创建的运行时配置的名称。

我们将配置一些总体属性,这些属性将作为默认值(在没有覆盖的情况下),位于 src/main/resources/application.properties 中。

src/main/resources/application.properties。

management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=*

greeting = Hello ${user.name} (running on ${os.name} ${os.version})!
  • 对于此演示,我们希望公开所有 Actuator 端点以能够对其进行查询。在任何其他上下文中:配置安全性!

  • 我们希望包含所有 Actuator 端点

现在让我们转向 Java 代码。您需要将以下依赖项添加到您的构建中:org.springframework.boot : spring-boot-starter-weborg.springframework.boot : spring-boot-starter-actuatororg.springframework.cloud : spring-cloud-gcp-starter-config。我们添加 Spring Cloud GCP 依赖项以获取 Runtime Config 支持的正确配置。我们添加 Spring Boot Actuator,以便我们可以访问一些操作端点,/actuator/env/actuator/refresh

让我们看看一些代码!

package com.example.gcp.runtimeconfig;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class RuntimeConfigApplication {

        @RefreshScope 
        @RestController
        public static class GreetingsRestController {

                private final String greetings;

                
                GreetingsRestController(@Value("${greeting}") String greetings) {
                        this.greetings = greetings;
                }

                @GetMapping("/greeting")
                String greetings() {
                        return this.greetings;
                }
        }

        public static void main(String[] args) {
                SpringApplication.run(RuntimeConfigApplication.class, args);
        }
}
  • 此注释支持修改和刷新此 Bean 的配置。我们可以触发刷新事件并在 Bean 中观察更新的配置

  • 我们正在从属性文件或 GCP Runtime Config 中注入密钥。在代码方面,它完全相同。

在没有激活任何配置文件的情况下运行此程序,当您访问 https://127.0.0.1:8080/greeting 处的端点时,您应该会看到类似于 Hello jlong! 的内容。访问此环境 Actuator 端点 (https://127.0.0.1:8080/actuator/env),您将找不到我们 GCP Runtime Config 配置的任何提及。现在,在激活了 cloud 配置文件的情况下运行程序,然后再次访问 /greeting 端点,您将在控制台输出中看到类似于 Hello GCP 的内容。访问 /actuator/env 端点,您将看到一个 bootstrapProperties:spring-cloud-gcp 条目,其中包含我们的 Runtime Config 值。

提示

您可以通过指定 -Dspring.profiles.active=foo,bar(用于配置文件 foobar)来更改活动配置文件,以便在运行应用程序时使用。

到目前为止,我非常喜欢我们的应用程序,但问候语听起来太生硬了!我想更改它,但不想停止和启动每个应用程序实例。在这里,我们可以利用 /actuator/refresh 端点来在更新 Runtime Config 配置中的值后刷新节点的配置。让我们将值更改为不太正式的内容,例如 Hi, GCP

gcloud beta runtime-config configs variables set greeting  "Hi, GCP"  --config-name reservations_cloud

配置已在 GCP Runtime Config 中更改,但至少默认情况下,该更改对我们的应用程序不可见。我们需要强制 Spring Boot 刷新其本地配置,从 Runtime Config 服务中提取配置。向 /actuator/refresh 端点发出(空的)HTTP POST 命令,然后访问 /greeting 端点以查看更新的值。

curl https://127.0.0.1:8080/greeting
> Hello GCP

gcloud beta runtime-config configs variables set greeting  "Hi GCP"  --config-name reservations_cloud
curl -H"content-type: application/json" -d{} https://127.0.0.1:8080/actuator/refresh
curl https://127.0.0.1:8080/greeting
> Hi GCP
  • 检查旧值

  • 更改值,然后强制客户端刷新其配置。您将能够确认更新。

获取 Spring 电子报

与 Spring 电子报保持联系

订阅

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多信息

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部