Learning objectives
Article reprint Le byte
Service configuration status
Configuration files are familiar to us. In the microservice system, each microservice not only has code, but also needs to connect other resources, such as database configuration or functional switch MySQL, Redis, Security and other related configurations. In addition to the basic configuration of project operation, there are some configurations related to our business, such as seven cattle storage, SMS and email, or some business switches.
However, with the continuous iteration of the microservice system, the whole microservice system may become a network structure. At this time, the scalability, scalability, coupling and so on of the whole microservice system should be considered. One of the most important links is configuration management.
Disadvantages of general configuration management solutions
- Hard coding (code modification, cumbersome and high risk)
- properties or yml (replacement and restart are required in the cluster environment)
- xml (repackaging and restarting)
Why use Spring Cloud Config
Because conventional configuration management has great disadvantages, the centralized configuration center of Spring Cloud Config is used to manage the configuration information of each service.
Spring Cloud Config provides extensible configuration services in the way of Server server and Client client in the micro service distributed system. The Server provides the storage of the configuration file and provides the content of the configuration file in the form of interface; The Client obtains data through the interface and initializes its own application based on this data.
The configuration center is responsible for managing various environment profiles of all services.
The configuration center stores configuration files in Git by default, so we can easily deploy and modify them, which is helpful for version management of environment configuration.
What problems does Spring Cloud Config solve
Spring Cloud Config solves the problems of centralization, version control, platform independence and language independence of microservice configuration. Its characteristics are as follows:
- Provide server and client support (Spring Cloud Config Server and Spring Cloud Config Client)
- Application deployment in centralized management distributed environment
- Encryption and decryption of attribute values (symmetric and asymmetric encryption)
- Seamless integration with Spring applications based on Spring environment
- A program that can be developed in any language
- The default implementation is based on Git, and version management can be performed
Next, we will mainly talk about the use of Config from the following sections.
- Configuration center of basic version (without integration of Eureka)
- Integrated Eureka version of the configuration center
- Automatic refresh of configuration based on actor
- Encryption and decryption of attribute values (symmetric and asymmetric encryption)
- Automatic refresh of configuration based on Spring Cloud Bus
Environmental preparation
project
Config demo aggregation project.
- Eureka server: Registration Center (used to integrate the configuration center of Eureka version)
- eureka-server02: Registry (used to integrate the configuration center of Eureka version)
- Order service: order service (used to integrate the configuration center of Eureka version)
Warehouse
Config repo warehouse.
- Repository name: warehouse name
- Description (optional): warehouse description
- Public, Private: warehouse permission (public sharing, Private or designated partner)
- Initialize this repository with a README: add a readme md
- Add .gitignore: generate corresponding files for file types that do not require version management gitignore
- Add a license: certificate type, and generate the corresponding file LICENSE
configuration file
The configuration files of different environments are uploaded to the config repo warehouse.
The name of the configuration file is not random. For example, config-client-dev.yml and config-client-prod.yml are different environments of the same project. The project name is config client, one corresponds to the development environment and the other corresponds to the formal environment. Test represents the test environment.
config-client.yml
server: port: 7777 # port spring: application: name: config-client # apply name # Custom configuration name: config-client-default
config-client-dev.yml
server: port: 7778 # port spring: application: name: config-client # apply name # Custom configuration name: config-client-dev
config-client-test.yml
server: port: 7779 # port spring: application: name: config-client # apply name # Custom configuration name: config-client-test
config-client-prod.yml
server: port: 7780 # port spring: application: name: config-client # apply name # Custom configuration name: config-client-prod
Introductory case
Introductory case explanation: configuration center of basic version (without integration of Eureka)
Create server
Create the sub project config server under the config demo parent project.
Add dependency
Add spring cloud config server dependency, complete POM The 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>com.xxxx</groupId> <artifactId>config-server</artifactId> <version>1.0-SNAPSHOT</version> <!-- Inherit parent dependency --> <parent> <groupId>com.xxxx</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- Project dependency --> <dependencies> <!-- spring cloud config server rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- spring boot test rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
configuration file
server: port: 8888 # port spring: application: name: config-server # apply name cloud: config: server: git: uri: https://github. Warehouse address of COM / XXXX / config repo # configuration file #username: # Login account of Github and other products #password: # Login password of Github and other products #default-label: master # Profile branch #search-paths: # Root directory of configuration file
Startup class
Add @ EnableConfigServer annotation to the startup class.
package com.xxxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; // Configuration center server annotation @EnableConfigServer @SpringBootApplication public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
Access rules
Spring Cloud Config has a set of access rules. We can directly access it on the browser through this set of rules.
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
- {application}: application name (target service name)
- {profile}: get the specified environment configuration. The project includes development environment, test environment and production environment. The corresponding configuration file is based on Application - {profile} YML, such as application-dev.yml and application test yml,application-prod.yml. The default value is default.
- {label}: indicates the git branch. The default is the master branch. If the project is distinguished by branches, you can control access to different configuration files through different labels.
Create client
Create the sub project config client under the config demo parent project.
Add dependency
Add spring cloud starter config dependency, complete POM The 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>com.xxxx</groupId> <artifactId>config-client</artifactId> <version>1.0-SNAPSHOT</version> <!-- Inherit parent dependency --> <parent> <groupId>com.xxxx</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- Project dependency --> <dependencies> <!-- spring cloud starter config rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- spring boot web rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- spring boot test rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
configuration file
The client configuration file name must be called bootstrap yml
spring: cloud: config: name: config-client # The name of the configuration file corresponds to the first half of the configuration file in the git warehouse uri: http://Localhost: 8888 # config server server server address label: master # git branch profile: default # Specify environment
Control layer
Add a RestController to test and obtain configuration file information.
package com.xxxx.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigController { @Value("${name}") private String name; @GetMapping("/name") public String getName() { return name; } }
Startup class
package com.xxxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } }
test
Modify the configuration file to dev environment:
spring: cloud: config: name: config-client # Application name, corresponding to the first half of the configuration file in git warehouse uri: http://Localhost: 8888 # config server server server address label: master # git branch profile: dev # Specify environment
Spring Cloud Config high availability
The above describes the most basic usage of Spring Cloud Config. If Eureka is used as the service registration and discovery center in our project, Spring Cloud Config should also be registered with Eureka to facilitate the use of other services, and multiple configuration center servers can be registered to achieve high availability.
Next, integrate Spring Cloud Config into Eureka. You can read my history articles about Eureka.
Add profile
Add configuration files in Github repository.
order-service-dev.yml
server: port: 9090 # port spring: application: name: order-service # apply name # Configure Eureka Server registry eureka: instance: prefer-ip-address: true # Whether to register with ip address instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # Set service registry address defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ # Custom configuration name: order-service-dev
order-service-prod.yml
server: port: 9091 # port spring: application: name: order-service # apply name # Configure Eureka Server registry eureka: instance: prefer-ip-address: true # Whether to register with ip address instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # Set service registry address defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ # Custom configuration name: order-service-prod
Integrated registry
The case has been prepared for you. You can use it directly without creating a registration center. For clarity, post the dependency and configuration information to you.
rely on
The core dependencies of Eureka server and Eureka Server02 are consistent.
<?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>com.xxxx</groupId> <artifactId>eureka-server</artifactId> <version>1.0-SNAPSHOT</version> <!-- Inherit parent dependency --> <parent> <groupId>com.xxxx</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- Project dependency --> <dependencies> <!-- netflix eureka server rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- spring boot web rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- spring boot test rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
configuration file
Eureka server application yml
server: port: 8761 # port spring: application: name: eureka-server # Application name (same under cluster) # Configure Eureka Server registry eureka: instance: hostname: eureka01 # Host name. If it is not configured, it will be obtained according to the host name of the operating system prefer-ip-address: true # Whether to register with ip address instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: # Set the service registry address and point to another registry service-url: # Registered address of the registry defaultZone: http://localhost:8762/eureka/
Application of eureka-server02 yml
server: port: 8762 # port spring: application: name: eureka-server # Application name (same under cluster) # Configure Eureka Server registry eureka: instance: hostname: eureka02 # Host name. If it is not configured, it will be obtained according to the host name of the operating system prefer-ip-address: true # Whether to register with ip address instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: # Set the service registry address and point to another registry service-url: # Registered address of the registry defaultZone: http://localhost:8761/eureka/
Startup class
The core codes of Eureka server and Eureka Server02 startup classes are consistent.
package com.xxxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication // Open EurekaServer annotation @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
Spring Cloud Config server
Compared with the configuration center of the basic version, the server has more Eureka configuration, which is the same in other places.
After the config server server is built, a config Server02 is reproduced to achieve high availability.
rely on
The core dependencies of config server and config Server02 are consistent. Note the spring cloud config server dependency.
<?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>com.xxxx</groupId> <artifactId>config-server</artifactId> <version>1.0-SNAPSHOT</version> <!-- Inherit parent dependency --> <parent> <groupId>com.xxxx</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- Project dependency --> <dependencies> <!-- spring cloud config server rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- netflix eureka client rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- spring boot test rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
configuration file
Config server application yml
server: port: 8888 # port spring: application: name: config-server # apply name cloud: config: server: git: uri: https://github. Warehouse address of COM / XXXX / config repo # configuration file #username: # Login account of Github and other products #password: # Login password of Github and other products #default-label: master # Profile branch #search-paths: # Root directory of configuration file # Configure Eureka Server registry eureka: instance: prefer-ip-address: true # Whether to register with ip address instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # Set service registry address defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
Application.config-server02 yml
server: port: 8889 # port spring: application: name: config-server # apply name cloud: config: server: git: uri: https://github. Warehouse address of COM / XXXX / config repo # configuration file #username: # Login account of Github and other products #password: # Login password of Github and other products #default-label: master # Profile branch #search-paths: # Root directory of configuration file # Configure Eureka Server registry eureka: instance: prefer-ip-address: true # Whether to register with ip address instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # Set service registry address defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
Startup class
The core codes of config server and config Server02 startup classes are consistent.
package com.xxxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; // Open the Eureka client annotation. If the Eureka registry is configured in the current version, the annotation will be opened by default //@EnableEurekaClient // Configuration center server annotation @EnableConfigServer @SpringBootApplication public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
Spring Cloud Config client
After the client joins Eureka, it does not need to deal directly with the server of the configuration center, but accesses it through Eureka.
rely on
POM of order service xml. Note the spring cloud starter config dependency.
<?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>com.xxxx</groupId> <artifactId>order-service</artifactId> <version>1.0-SNAPSHOT</version> <!-- Inherit parent dependency --> <parent> <groupId>com.xxxx</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- Project dependency --> <dependencies> <!-- spring boot web rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- netflix eureka client rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- spring cloud starter config rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- spring boot test rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
configuration file
Bootstrap of order service yml
spring: cloud: config: name: order-service # The name of the configuration file corresponds to the first half of the configuration file in the git warehouse label: master # git branch profile: dev # Specify environment discovery: enabled: true # open service-id: config-server # Specify the service ID of the configuration center server
Control layer
Add a RestController to test and obtain configuration file information.
package com.xxxx.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigController { @Value("${name}") private String name; @GetMapping("/name") public String getName() { return name; } }
Startup class
package com.xxxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // Open the Eureka client annotation. If the Eureka registry is configured in the current version, the annotation will be opened by default //@EnableEurekaClient @SpringBootApplication public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
Article reprint Le byte