Introduction
Spring Cloud provides a platform for deploying microservices, including common components in microservices: configuration center services, API gateways, circuit breakers, service registration and discovery, distributed traceability, OAuth2, consumer-driven contracts, etc. We don't have to know what each component does first, we'll get to them gradually as the tutorial progresses. The general structure of a distributed service is shown in the following figure (picture from: spring.io ):
Building a distributed system with Spring Cloud is very simple. We only need a few lines of simple configuration to start a series of components, and then we can control, use and manage these components in code. Spring Cloud uses Spring Boot as the basic framework. You can refer to my last blog on how to create a Spring Boot project, Spring Boot 2.0.1 Getting Started Tutorial . This tutorial will teach you how to configure the service center service and read the configuration through the web client.
basic environment
- JDK 1.8
- Maven 3.3.9
- IntelliJ 2018.1
- Git
Project source code
Create Web Client
First create a Maven project with IntelliJ, the content of the pom.xml file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.zxuqian</groupId>
<artifactId>web</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
dependencyManagement
You can specify a unified version number for all dependencies. The Spring-cloud dependency version here is Finchley.M9, and then userepository
the repository that specifies this version.spring-cloud-starter-config
Provides an API interface to access configuration center services.
add controller
Create a new controller class cn.zxuqian.controllers.HelloController
and add the following code:
package cn.zxuqian.controllers;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope
@RestController
public class HelloController {
@Value("${message: 本地消息}")
private String message;
@RequestMapping("/message")
public String message() {
return this.message;
}
}
A simple controller that matches a /message
path, and returns message
the value of a variable. Don't worry @RefreshScope
about this , I'll talk about it later. @Value
It will take the configuration items from the configuration center service, or local environment variables, etc. Here, message
the value of the configuration center is taken, and it is given a default value of "local message", that is, if the remote configuration center is unavailable, this variable will be will be initialized with default values.
Add configuration file
bootstrap.xml
We need to load the configuration items of the configuration center before the web client project is fully started, so we need src/main/resources
to create a bootstrap.yml
file below, and then specify the name of the client and the uri of the remote configuration center:
spring:
application:
name: web-client
cloud:
config:
uri: http://localhost:8888
Compared with the properties file, yml is more concise and does not need to write many repeated prefixes. The above content can be converted into the corresponding properties:
spring.application.name=web-client
spring.cloud.config.uri=http://localhost:8888
spring.application.name
The name of this project is specified, and it is used to obtain the configuration file with the same file name in the configuration center, that is, the configuration center should have aweb-client.yml
configuration file with the file name.spring.cloud.config.uri
The uri address of the remote configuration center service is specified, the default is ** http://localhost:8888**
Create a Configuration Center project
Create a new Maven project and use the following pom configuration:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.zxuqian</groupId>
<artifactId>config-server</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
spring-cloud-config-server
It is the core dependency of the configuration center service.
Configure Application
Create a new Java class cn.zxuqian.Application
and add the following code:
package cn.zxuqian;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- Use
@EnableConfigServer
this annotation to start the Maven project as a configuration center service.
Create a new Git repository
The files in the configuration center are all based on version control, so you need to create a git repository locally to save the configuration files. Or you can also use public remote git repositories, github, code cloud, etc. Create a blank folder in any location (such as the project's parent directory), here it is called config
, you can use any name. Then go to this folder and run
$ git init
to initialize the git repository, then create a new file named web-client.yml
and add the following:
message: 此条消息来自于cofig server
Note that this filename needs to be the spring.application.name
same as previously configured in the web project. The content of this file is the value of the message to be obtained by the web client. After the creation is complete, run the following git command to submit to the local repository:
$ git add web-client.yml
$ git commit -m "added web-client.yml"
Configure git repository location
We need to specify the git repository address created above for the configuration center. src/main/resources
Create a applicaiton.yml
file under, providing the following content:
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: ${HOME}/development/codes/backend/gitee/config
This file specifies the port number of the configuration center service and the git warehouse directory where the configuration file is saved. If it is a remote warehouse, you can directly specify the url address. At this point, the configuration center service is created.
test
First start the configuration center service and use the spring-boot maven plugin: spring-boot:run. After the startup is successful, start the web client, access http://localhost:8080/message
, and if you see 此条消息来自于cofig server
it, the configuration is successful. Then close the configuration center service, restart the web client, visit http://localhost:8080/message
, and we will see it 本地消息
.
Dynamically update configuration
So is it troublesome to restart every time the configuration is updated? Spring boot provides spring-boot-starter-actuator
components for maintaining the production environment, such as checking health information. Remember HelloController
the @RefreshScope
note above? Using it we can dynamically load the modified configuration of the configuration center. Then we also need to add the following content in the configuration center to expose the terminal api of web-client.yml
acurator ./refresh
message: 此条消息来自于cofig server
management:
endpoints:
web:
exposure:
include: "*"
The git repository submitted after the update is completed, and then restart the configuration center service and web client. Modify the message to
message: 更新:此条消息来自于cofig server
Then send an empty post request to/refresh
$ curl http://localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"
After refreshing the page, you can see the updated message.
Summarize
Now we have built a configuration center service, which spring.application.name
determines which configuration file to read according to each component, and then we use acurator's /refresh
api to refresh the configuration items at runtime. In addition, the configuration items are all based on version control, which can be easily restored and updated. Through this tutorial, you can see that the configuration of each component of Spring Cloud is quite simple. Basically, only one annotation can be used to create a complete service component.
Welcome to the original text of my blog: Spring Cloud Getting Started Tutorial - Building a Configuration Center Service