In SpringCloud Config, if multiple microservice clients obtain configuration information from the service configuration center, once the configuration file in the remote library is modified, the service configuration center can update synchronously, but the modification of configuration information cannot be synchronized to each microservice immediately, We can update the configuration information by sending a post request to the micro service to refresh the micro service. We hope that: 1. Each micro service does not need to send a post request one by one or manually refresh one by one. A notification enables each micro service to obtain the latest configuration information; 2. Further, let the micro service that modifies the configuration information modify the information, and the micro service that does not modify the configuration information will not be modified.
Spring Cloud Bus is a framework used to link the nodes of distributed system with lightweight message system. It integrates the time processing mechanism of Java and the functions of message middleware. Specifically, it has the function of distributed automatic refresh configuration. Spring Cloud Bus can be used with Spring Cloud Config to realize the dynamic refresh of configuration; Currently, two message brokers are supported: RabbitMQ and Kafka
SpringCloud can manage and disseminate information between distributed systems, just like a distributed actuator, which can be used to broadcast state changes, time push, etc. it can also be used as a communication channel between microservices.
Main functions:
Bus
In microservice architecture systems, lightweight message brokers are usually used to build a common message topic and link 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. Each instance on the bus can easily broadcast some messages that need to be known by other instances connected to the subject.
Basic principles
ConfigClient instances listen to the same Topic(Spring Cloud Bus) in MQ. When a service refreshes the data, it will put this information into the Topic, so that other micro services listening to the same Topic can be notified, and then update their own configuration.
RabbitMQ installation (Linux system)
Install Docker first and then run the following command: see the installation steps of Docker Official document of Docker
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management
##############Set RabbitMQ auto start#######################
docker update rabbitmq --restart=always
##############Log in to the login page of RabbitMQ management side#################
http: / / server IP address: 15672
The default user name and password are guest
Spring cloud bus dynamically refreshes global broadcast
Add a new microservice module
To notify multiple microservices, you need to create a cloud-config-client-3366 module
1. POM file
<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.atyixuan</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>
2,bootstrap.yml profile
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: "*"
3. Main startup class: com atyixuan. springcloud. ConfigClientMain3366
@EnableEurekaClient @SpringBootApplication public class ConfigClientMain3366 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3366.class, args); } }
4. Business class: com atyixuan. springcloud. controller. ConfigClientController
@RestController @RefreshScope public class ConfigClientController { @Value("${server.port}") private String serverPort; @Value("${config.info}") private String configInfo; @GetMapping(value = "/configInfo") public String getConfigInfo() { return "server port: " + serverPort + "\t\n\n configInfo: " + configInfo; } }
design idea
1) Use the message bus to trigger a client / bus/refresh and refresh the configuration of all clients
2) use the message bus to trigger the / bus/refresh endpoint of a server ConfigServer and refresh the configuration of all clients (more recommended). Compared with the following figure, the above figure is inappropriate for the following reasons:
- It breaks the single responsibility of microservice, because microservice itself is a business module, 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 migrating a microservice, its network address often changes. At this time, if you want to refresh automatically, you will add more modifications
Modification of configuration center and two microservices
Add message bus support to cloud-config-center-3344 configuration center server and add new dependencies in its POM file:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Modify the YML configuration file:
server: port: 3344 spring: application: name: cloud-config-center cloud: config: server: git: uri: https://github.com/hhf19906/springcloud-config.git #git@github.com:hhf19906/springcloud-config.git search-paths: - springcloud-config label: master # Using rabbitMQ messaging middleware rabbitmq: host: The server IP address port: 5672 username: guest password: guest eureka: client: service-url: defaultZone: http://localhost:7001/eureka management: endpoints: web: exposure: # This corresponds to / bus/refresh in the figure above include: 'bus-refresh'
Add message bus support to cloud-config-center-3355 client and add new dependencies in its POM file:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Modify the YML configuration file:
server: port: 3355 spring: application: name: config-client cloud: config: label: master name: config profile: dev uri: http://localhost:3344 rabbitmq: host: The server ip address port: 5672 username: guest password: guest eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka management: endpoints: web: exposure: include: "*"
Add message bus support to cloud-config-center-3366 client and add new dependencies in its POM file:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Modify the YML configuration file:
server: port: 3366 spring: application: name: config-client cloud: config: label: master name: config profile: dev uri: http://localhost:3344 rabbitmq: host: The server ip address port: 5672 username: guest password: guest eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka management: endpoints: web: exposure: include: "*"
Test:
Start in sequence
cloud-eureka-server7001 cloud-config-center3344
cloud-config-client-3355 cloud-config-client-3366 Enter in the browser: http://config-3344.com:3344/config-dev.yml
http://localhost:3355/configInfo
http://localhost:3366/configInfo
At this time, modify the configuration information in the remote Git and change the version number to 5
Use curl to send a POST request to refresh cloud-config-center3344
curl -X POST "http://localhost:3344/actuator/bus-refresh"
http://localhost:3355/configInfo Browser access again http://localhost:3355/configInfo And http://localhost:3366/configInfo
The results are as follows:
The configuration information obtained by the two microservices has been updated, realizing the purpose of one modification and taking effect everywhere
Spring cloud bus dynamic refresh fixed-point notification
In the previous step, we realized the dynamic refresh of the global broadcast. We hope to further let only some micro services receive notifications, and some micro services do not receive notifications.
Formula: http://localhost: Port number of configuration center / Actor / bus refresh / {destination}
/The bus/refresh request is no longer sent to the specific service instance, but to the config server and specifies the service or instance that needs to update the configuration through the destination parameter class
According to the above micro service, only cloud-config-client-3355 will be notified and cloud-config-client-3366 will not be notified
When refreshing the service configuration center cloud-config-center3344, only refresh cloud-config-client-3355
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"
Modify the content of the configuration file in Git remote library again
Curl refresh cloud-config-center3344
cloud-config-client-3355 received the notification, but cloud-config-client-3366 did not
The whole process is shown in the figure below