中心化配置

中心化配置

中心化配置

Centralized Configuration

此教程指导你构建一个Spring Cloud配置服务器,并从其中消费配置。

This guide walks you through the process of standing up, and consuming configuration from, the Spring Cloud Config Server

将要做什么

What you’ll build

你将构建一个配置服务器,然后建立一个客户端在启动时去消费配置并在不重启客户端的情况下刷新配置。

You’ll setup a Config Server and then build a client that consumes the configuration on startup and then refreshes the configuration without restarting the client.

需要些什么

What you’ll need

如何完成此教程

How to complete this guide

与大多数Spring的入门教程相似,你可以从头开始并完成每一步,或者你也可以跳过你熟悉的设置步骤。无论怎样,你最终应当以有效代码结束。

Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.

如果从头开始,可参考使用Gradle构建

To start from scratch, move on to Build with Gradle.

如果要跳过基本步骤,按如下步骤:

To skip the basics, do the following:

  • 下载并解压此教程的源码仓库,或者使用Git进行clone:git clone https://github.com/spring-guides/gs-centralized-configuration.git
  • 进入gs-centralized-configuration/initial目录
  • 跳至构建一个配置服务器.
  • Download and unzip the source repository for this guide, or clone it using Git: git clone https://github.com/spring-guides/gs-centralized-configuration.git
  • cd into gs-centralized-configuration/initial
  • Jump ahead to Stand up a Config Server.

当你完成时,你可以与gs-centralized-configuration/complete中的代码对比检查。

When you’re finished, you can check your results against the code in gs-centralized-configuration/complete.

构建一个配置服务器

Stand up a Config Server

首先你需要一个配置服务来作为Spring应用和配置文件版本控制库的媒介。可以使用Spring Cloud的@EnableConfigServer来构建一个供其他应用访问的配置服务器。这是通过添加注解来启用配置服务器的一个通常Spring Boot应用。

You’ll first need a Config Service to act as a sort of intermediary between your Spring applications and a typically version-controlled repository of configuration files. You can use Spring Cloud’s @EnableConfigServer to stand up a config server that other applications can talk to. This is a regular Spring Boot application with one annotation added to enable the config server.

configuration-service/src/main/java/hello/ConfigServiceApplication.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServiceApplication.class, args);
    }
}

配置服务器需要知道管理哪个库。这里有多种选择,我们将使用基于Git的文件系统库。你可以根据自己情况选择将配置服务器连接到Github或者GitLab库。在此文件系统中,创建一个新的目录,并执行git init。然后在Git库中添加一个名为a-bootiful-client.properties的文件。然后执行git commit提交此文件。稍后你将把一个属性名为spring.application.name值为as a-bootiful-client的Spring Boot应用连接到配置服务器。这是让配置服务器知道需要发送哪些配置到指定的客户端。同时也会发送Git库中所有的名为application.properties或者application.yml的文件中的值。在指定文件名(例如a-bootiful-client.properties)中的属性值将会覆盖application.properties或者application.yml中的值。

The Config Server needs to know which repository to manage. There are several choices here, but we’ll use a Git-based filesystem repository. You could as easily point the Config Server to a Github or GitLab repository, as well. On the file system, create a new directory and git init it. Then add a file called a-bootiful-client.properties to the Git repository. Make sure to also git commit it, as well. Later, you will connect to the Config Server with a Spring Boot application whose spring.application.name property identifies it as a-bootiful-client to the Config Server. This is how the Config Server will know which set of configuration to send to a specific client. It will also send all the values from any file named application.properties or application.yml in the Git repository. Property keys in more specifically named files (like a-bootiful-client.properties) override those in application.properties or application.yml.

在新建的a-bootiful-client.properties文件中加入一个属性和值,message = Hello world,然后git commit提交。

Add a simple property and value, message = Hello world, to the newly created a-bootiful-client.properties file and then git commit the change.

通过在configuration-service/src/main/resources/application.properties中设置属性spring.cloud.config.server.git.uri来指定Git库的路径。如果在同一台机器上运行此服务与其他Spring Boot应用时,注意设置不同的server.port值避免端口冲突。

Specify the path to the Git repository by specifying the spring.cloud.config.server.git.uri property in configuration-service/src/main/resources/application.properties. Make sure to also specify a different server.port value to avoid port conflicts when you run both this server and another Spring Boot application on the same machine.

configuration-service/src/main/resources/application.properties

server.port=8888

spring.cloud.config.server.git.uri=${HOME}/Desktop/config

此例中我们使用了位于${HOME}/Desktop/config的基于文件的git库。你可以通过新建文件夹并git提交属性与YAML文件来创建一个。

In this example we are using a file-based git repository at ${HOME}/Desktop/config. You can create one easily by making a new directory and git committing properties and YAML files to it. E.g.

$ cd ~/Desktop/config
$ find .
./.git
...
./application.yml

或者你也可以改变应用配置文件,来使用一个远程git库,例如github。

Or you could use a remote git repository, e.g. on github, if you change the configuration file in the application to point to that instead.

使用配置客户端从配置服务端读取配置

Reading Configuration from the Config Server using the Config Client

现在我们已经建好了配置服务器,让我们建一个新的Spring Boot应用来使用配置服务器加载其配置并根据服务器变化来刷新配置,这些都无需重启JVM。添加org.springframework.cloud:spring-cloud-starter-config依赖来连接匹配置服务器。Spring将会像读取application.properties或者application.yml或其他PropertySource一样查看配置文件。

Now that we’ve stood up a Config Server, let’s stand up a new Spring Boot application that uses the Config Server to load its own configuration and that refreshes its configuration to reflect changes to the Config Server on-demand, without restarting the JVM. Add the org.springframework.cloud:spring-cloud-starter-config dependency in order to connect to the Config Server. Spring will see the configuration property files just like it would any property file loaded from application.properties or application.yml or any other PropertySource.

用于设置配置客户端的属性必须要在应用的其他配置读取之前完成。指定客户端的spring.application.namea-bootiful-client和在configuration-client/src/main/resources/bootstrap.properties中配置服务器的地址spring.cloud.config.uri,这些都将先于其他配置被读取。

The properties to configure the Config Client must necessarily be read in before the rest of the application’s configuration is read from the Config Server, during the bootstrap phase. Specify the client’s spring.application.name as a-bootiful-client and the location of the Config Server spring.cloud.config.uri in configuration-client/src/main/resources/bootstrap.properties, where it will be loaded earlier than any other configuration.

configuration-client/src/main/resources/bootstrap.properties

spring.application.name=a-bootiful-client
# N.B. this is the default:
spring.cloud.config.uri=http://localhost:8888

同时我们希望启用/refresh端点来表示动态配置变更:

We also want to enable the /refresh endpoint so that we can demonstrate dynamic configuration changes:

configuration-client/src/main/resources/application.properties

management.endpoints.web.exposure.include=*

此客户端可使用传统的方式(例如@ConfigurationProperties, @Value("${…​}")或者通过Environment抽象)访问配置服务器上的任何值。创建一个Spring MVC REST控制器并返回解析的message属性值。查看构建一个RESTful Web服务来学习更多关于使用Spring MVC和Spring Boot来构建REST服务。

The client may access any value in the Config Server using the traditional mechanisms (e.g. @ConfigurationProperties, @Value("${…​}") or through the Environment abstraction). Create a Spring MVC REST controller that returns the resolved message property’s value. Consult the Building a RESTful Web Service guide to learn more about building REST services with Spring MVC and Spring Boot.

默认配置值将在客户端启动的时候读取,后续不再重新读取。你可以在MessageRestController添加Spring Cloud Config的注解@RefreshScope并通过触发其刷新事件,强制一个bean刷新配置,用来从配置服务器获取更新值。

By default, the configuration values are read on the client’s startup, and not again. You can force a bean to refresh its configuration – to pull updated values from the Config Server – by annotating the MessageRestController with the Spring Cloud Config @RefreshScope and then by triggering a refresh event.

configuration-client/src/main/java/hello/ConfigClientApplication.java

package hello;

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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class ConfigClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class, args);
    }
}

@RefreshScope
@RestController
class MessageRestController {

    @Value("${message:Hello default}")
    private String message;

    @RequestMapping("/message")
    String getMessage() {
        return this.message;
    }
}

测试应用

Test the application

先启动配置服务器,启动完成后再启动客户端。在浏览器中通过http://localhost:8080/message访问客户端应用。你可以看见表示响应的字符串Hello world

Test the end-to-end result by starting the Config Service first and then, once loaded, starting the client. Visit the client app in the browser, http://localhost:8080/message. There, you should see the String Hello world reflected in the response.

修改Git库中a-bootiful-client.properties文件的message对应值(例如改为Hello Spring!)。你可以通过访问http://localhost:8888/a-bootiful-client/default来确认配置服务器是否检测到变更。你需要调用Spring Boot Actuator端点refresh来强制客户端刷新并放入新值。Spring Boot的Actuator暴露了一些可选端点,例如健康检查、环境信息、关于应用等等。需要在客户端应用的CLASSPATH增加org.springframework.boot:spring-boot-starter-actuator才能使用。可通过发送一个空HTTP POST到客户端的refresh端点来调用Actuator的refresh端点,然后可通过访问http://localhost:8080/message来确认是否起效。

Change the message key in the a-bootiful-client.properties file in the Git repository to something different (Hello Spring!, perhaps?). You can confirm that the Config Server sees the change by visiting http://localhost:8888/a-bootiful-client/default. You need to invoke the refresh Spring Boot Actuator endpoint in order to force the client to refresh itself and draw the new value in. Spring Boot’s Actuator exposes operational endpoints, like health checks and environment information, about an application. In order to use it you must add org.springframework.boot:spring-boot-starter-actuator to the client app’s CLASSPATH. You can invoke the refresh Actuator endpoint by sending an empty HTTP POST to the client’s refresh endpoint, http://localhost:8080/actuator/refresh, and then confirm it worked by reviewing the http://localhost:8080/message endpoint.

$ curl localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"

在客户端应用中设置management.security.enabled=false,可以使测试更简单(Spring Boot 1.5后Actuator端点默认是安全的)。如果不设置此标记,默认你可以通过JMX来访问。

we set management.security.enabled=false in the client app to make this easy to test (by default since Spring Boot 1.5 the Actuator endpoints are secure by default). By default you can still access them over JMX if you don’t set the flag.

总结

Summary

恭喜!你完成了使用Spring来为你的所有服务提供中心化配置,并可以动态更新配置。

Congratulations! You’ve just used Spring to centralize configuration for all your services by first standing up a and to then dynamically update configuration.

翻译部分版权归YahaCode团队所有。仅供学习研究之用,任何组织或个人不得私自以此用于任何形式的商业目的

发表评论