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

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

各位Spring的粉丝们大家好!在这个简短的8部分系列中,我们将探讨Spring Cloud对Google Cloud Platform的集成,该集成被称为Spring Cloud GCP。 Spring Cloud GCP 是Google和Pivotal之间的一项合作项目,旨在为使用Google Cloud Platform的Spring Cloud开发者提供一流的体验。Pivotal Cloud Foundry用户将享受到与GCP服务代理 更简单的集成。我撰写这些章节时,得到了Google Cloud开发者倡导者、我的朋友 Ray Tsang 的协助。您也可以在我们的Google Next 2018会议 Bootiful Google Cloud Platform 中观看Spring Cloud GCP的演示。谢谢你,朋友!一如既往,如果您有任何反馈, 我很乐意倾听

该系列共有八篇文章。以下是全部内容:

](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配置文件时,禁用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配置文件,届时Spring Cloud GCP Runtime Config客户端将启动并从GCP获取配置。Spring Boot很智能,除了默认配置外,还会加载任何特定于配置文件的配置。您只需在配置文件名称后加上-${YOUR_PROFILE}即可:例如,对于Spring配置文件foobar,分别是application-foo.propertiesbootstrap-bar.yml。让我们配置Spring Cloud GCP,以便在cloud配置文件激活时使用。

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,这就是我们刚刚创建的Runtime Configuration的名称。

我们将在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://:8080/greeting端点时,您应该会看到类似Hello jlong!的内容。访问此环境Actuator端点(https://: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://: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://:8080/actuator/refresh
curl https://:8080/greeting
> Hi GCP
  • 检查旧值

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

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

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

查看所有