1,Config
1.1 overview
1. Problems faced by distributed
- Microservice means to split the business in a single application into one sub service. The granularity of each service is relatively small, so there will be a large number of services in the system. Because each service needs the necessary configuration information to run, a centralized and dynamic configuration management facility is essential.
2. What is config
- Spring Cloud Config is divided into server and client.
- The server also becomes a distributed configuration center. It is an independent micro service application, which is used to connect to the configuration server and provide access interfaces for the client to obtain configuration information, encryption / decryption information and so on.
- The client manages application resources and business-related configuration contents through the specified configuration center, and obtains and loads configuration information from the configuration center at startup. The configuration server uses git to store configuration information by default, which is helpful for version management of environment configuration, And the GIT client tool can be used to manage and access the configuration content conveniently.
3. What can I do
- Centrally manage profiles
- Different environments have different configurations, dynamic configuration updates, and deployment by environment, such as dev/test/prod/beta/release
- The configuration is dynamically adjusted during operation. It is no longer necessary to write configuration files on each service deployed machine. The service will uniformly pull and configure its own information from the configuration center
- When the configuration changes, the service can sense the configuration changes and apply the new configuration without restarting
- Expose the configuration information in the form of REST interface
1.2 configuration and test of Config server
1. Build Module
- The name of the Module is cloud-config-center-3344.
2. Change POM
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.xiao</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
3. Change YML
server: port: 3344 spring: application: name: cloud-config-center profiles: active: dev cloud: config: server: git: uri: https://gitee.com/henryxjh/springcloud-config.git # url address search-paths: # Search path - springcloud-config label: master # The main branch is configured eureka: client: service-url: defaultZone: http://localhost:7001/eureka
4. Main startup
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; @SpringBootApplication @EnableConfigServer public class ConfigCenterMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigCenterMain3344.class,args); } }
5. Test results
(1) . other access path formats
/{application}/{profile}[/{label}] /{application}-{profile}.yml ## This is recommended /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
1.3 configuration and test of Config client
1. Build Module
- The name of the Module is cloud-config-client-3355.
2. Change POM
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.xiao</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
3. Change YML
server: port: 3355 spring: application: name: config-client cloud: config: label: master name: config profile: dev uri: http://localhost:3344 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka
- To add application Change the yaml file name to bootstrap Yaml is the key, bootstrap Yaml is better than application Yaml is loaded first. And it is system level with higher priority.
- SpringCloud will create a Bootstrap Context as the parent context of the Application Context of the Spring application. During initialization, the Bootstrap Context is responsible for loading configuration properties from an external source and parsing the configuration. The two contexts share an Environment obtained from the outside.
4. Main startup
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3355.class,args); } }
5. Controller class
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigClientController { @Value("${spring.application.name}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){ return configInfo; } }
6. Test results
- As shown in the figure, we successfully read the content from the corresponding configuration file.
1.4. Dynamic refresh of Config client (manual version)
1.4.1 problems faced
-
Linux operation and maintenance modifies the content of the configuration file on GitHub to make adjustments
-
Refresh 3344 and find that the ConfigServer configuration center responds immediately
-
Refresh 3355 and find no response from ConfigServer client
-
3355 does not change unless you restart or reload yourself
1.4.2 dynamic refresh configuration and test
1. Introduction of POM into actor monitoring
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2. Add the following code to the yml file
management: endpoints: web: exposure: include: "*"
3. Modify the controller class
import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class ConfigClientController { @Value("${spring.application.name}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){ return configInfo; } }
4. You need to send a request to refresh the client
curl -X POST "http://localhost:3355/actuator/refresh"
5. Test results
(1) , access port 3344
(2) , access port 3355
2,Bus
2.1 overview
1. What is it
- Spring Cloud Bus is a framework used to connect the nodes of distributed systems with lightweight messaging systems. It integrates the event processing mechanism of Java and the functions of message middleware. Spring Cloud Bus currently supports RabbitMQ and Kafka.
- In microservice architecture systems, lightweight message brokers are usually used to build a common message topic and connect all microservice instances in the system. Since the messages generated in this topic will be monitored and consumed by all instances, it is called message bus. In each instance of the bus, you can easily broadcast some messages that need to be known to other instances connected to the subject.
- The principle is that all ConfigClient instances listen to the same topic in MQ, and the default is SpringCloudBus. When a service refreshes the data, it will put this message into the topic, so that other services listening to the same topic can be notified, and then update their own configuration.
2. What can I do
- Spring Cloud Bus can manage and propagate messages between distributed systems, just like a distributed actuator. It can be used to broadcast state changes, time push, etc. it can also be used as a communication channel between microservices.
2.2. Dynamic refresh in the form of global broadcast
2.2.1. Add a new client
1. Build Module
- The name of the Module is cloud-config-client-3366.
2. Change POM
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
3. Change YML
server: port: 3366 spring: application: name: config-client cloud: config: label: master name: config profile: dev uri: http://localhost:3344 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka management: endpoints: web: exposure: include: "*"
4. Main startup
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient @SpringBootApplication public class ConfigClientMain3366 { public static void main(String[] args) { SpringApplication.run( ConfigClientMain3366.class,args); } }
5. controller class
import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class ConfigClientController { @Value("${spring.application.name}") private String serverPort; @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){ return "serverPort:"+serverPort+"\t\n\n configInfo: "+configInfo; } }
2.2.2. Two methods of global dynamic refresh
- Use the message bus to trigger a client / bus/refresh and refresh the configuration of all clients
- Use the message bus to trigger the / bus/refresh endpoint of a server ConfigServer and refresh the configuration of all clients (more recommended)
(1) The second architecture is more appropriate
- It breaks the single responsibility of microservices, because microservices are business modules, which should not bear the responsibility of configuration refresh
- It destroys the peer-to-peer of micro service nodes
- There are certain limitations. For example, when a microservice is migrated, its network address often changes. At this time, if you want to refresh automatically, you will add more modifications.
2.2.3. Add the configuration supported by the message bus
1. Add message bus support to cloud-config-center-3344 configuration center server
(1),POM
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
(2) . newly added YML content
rabbitmq: host: localhost port: 5672 username: admin password: 123456
2. Add message bus support to cloud-config-center-3355 client
(1),POM
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
(2) . newly added YML content
rabbitmq: host: localhost port: 5672 username: admin password: 123456
3. Add message bus support to cloud-config-center-3366 client
(1),POM
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
(2) . newly added YML content
rabbitmq: host: localhost port: 5672 username: admin password: 123456
2.2.4 test results
- After sending the request curl - x post“ http://localhost:3344/actuator/bus -The test results after "Refresh" are as follows
- One amendment, broadcast notice, takes effect everywhere.
2.3 dynamic refresh in the form of fixed-point notification
- In the above environment in subsection 2.2, the request to notify only 3355 and not 3366 is as follows:
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"