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

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

Spring 粉丝们大家好!在这个由 8 部分组成的简短系列中,我们将探讨 Spring Cloud 对 Google Cloud Platform 的集成,称为 Spring Cloud GCPSpring 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 配置文件下运行时,这些值可能会被看到。当在 cloud 配置文件下运行时,我们将从 Google Cloud Runtime Config 获取这些值。通过这种方式,我们可以选择性地覆盖重要值。

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

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 profile 时,让我们禁用 Spring Cloud GCP Runtime Config。

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 profile,此时 Spring Cloud GCP Runtime Config 客户端将启动并从 GCP 获取配置。Spring Boot 在加载任何 profile 特定配置的同时加载默认配置方面非常智能。你只需将配置文件名后缀为 -${YOUR_PROFILE} 即可:例如:对于 Spring profile foobar,分别为 application-foo.propertiesbootstrap-bar.yml。让我们在 cloud profile 激活时配置 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})!
  • 对于这个 DEMO,我们希望暴露所有的 Actuator 端点,以便能够查询它们。在任何其他情况下:请配置安全性!

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

现在让我们转向 Java 代码。你需要将以下依赖项添加到你的构建中:org.springframework.boot : spring-boot-starter-web, org.springframework.boot : spring-boot-starter-actuator, org.springframework.cloud : spring-cloud-gcp-starter-config。我们添加 Spring Cloud GCP 依赖项以获取正确的运行时配置支持配置。我们添加 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 中注入键。就代码而言,它们完全相同。

在没有激活任何 profile 的情况下运行此程序,并在访问 http://localhost:8080/greeting 端点时,你应该会看到类似 Hello jlong! 的输出。访问这个环境 Actuator 端点 (http://localhost:8080/actuator/env),你会发现没有提及我们的 GCP Runtime Config 配置。现在,在激活 cloud profile 的情况下运行程序,再次访问 /greeting 端点,你会在控制台输出中看到类似 Hello GCP 的内容。访问 /actuator/env 端点,你会看到一个包含我们的 Runtime Config 值的 bootstrapProperties:spring-cloud-gcp 条目。

提示

你可以在运行应用程序时通过为 profile foobar 指定 -Dspring.profiles.active=foo,bar 来更改活动的 profile。

到目前为止我喜欢我们的应用程序,但问候语听起来太生硬了!我很想改变它,但又不想停止并重新启动每个应用程序实例。在这里,我们可以利用 /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 http://localhost: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{} http://localhost:8080/actuator/refresh
curl http://localhost:8080/greeting
> Hi GCP
  • 检查旧值

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

获取 Spring 新闻通讯

订阅 Spring 新闻通讯,保持联系

订阅

先行一步

VMware 提供培训和认证,助你加速前进。

了解更多

获取支持

Tanzu Spring 通过一项简单的订阅,为 OpenJDK™、Spring 和 Apache Tomcat® 提供支持和二进制文件。

了解更多

即将举行的活动

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

查看全部