SpringCloud Bus message bus
1. General
1.1 what is it
SpringCloud Bus can be used with Springcloud Config to dynamically refresh the configuration
It is a framework used to link the nodes of distributed system with lightweight message system. It integrates the event processing mechanism of Java and the function of message middleware.
Spring cloud Bus supports two message brokers: RabbitMQ and kafka
1.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, push events, etc. it can also be used as a communication channel between microservices
1.3 why is it called bus
- What is a bus:
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. Each instance on the bus can easily broadcast some messages that need to be known by other instances linked to the subject line. - Basic principle:
ConfigClient instances listen to the same topic in MQ (SpringcloudBus by default). When a service refreshes data, it will put this information into the topic, so that other services listening to the same topic can be notified, and then update their own configuration.
2. RabbitMQ environment configuration
reference resources: https://blog.csdn.net/zhou_zhao_xu/article/details/119378590
3. Spring cloud bus dynamically refreshes global broadcast
3.1 demonstrate the broadcast effect and increase the complexity. Take 3355 as the template and create cloud config center3366 configuration center service module in the parent project
1. Modify pom file
<?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"> <parent> <artifactId>springcloud</artifactId> <groupId>com.zzx</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-center3366</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- config --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- eureka client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </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>com.zzx</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
2. Write bootstrap Yaml profile
server: port: 3366 spring: application: name: cloud-config-client cloud: # config client configuration config: label: master # Branch name name: config # Profile name profile: dev # Suffix uri: http://localhost:3344 # configuration center address eureka: instance: instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} # Set instance access address prefer-ip-address: true # Set the access path to display the ip address client: # Indicates that you are registered with Eureka Server. The default value is true register-with-eureka: true # Whether to retrieve your existing registration information from Eureka Server. The default value is true. # Single node doesn't matter. The cluster must be set to true to use load balancing with ribbon fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka # Exposure monitoring endpoint management: endpoints: web: exposure: include: "*"
3. Write the main startup class
@SpringBootApplication @EnableEurekaClient public class MainConfigCenter3366 { public static void main(String[] args){ SpringApplication.run(MainConfigCenter3366.class,args); } }
4. Write test controller
@RestController @RefreshScope public class ConfigClientController { @Value("${server.port}") private String serverPort; @Value("${config.info}") private String configInfo; @Value("${config.message}") private String message; @GetMapping("/configInfo") public String getConfigInfo() { return "serverPort: " + serverPort + "\t\n\n" + configInfo + "\t\n\n" + message; } }
3.2 design idea
-
Use the message bus to trigger one client / bus/refresh and refresh all clients
-
Use the message bus to trigger the / bus/refresh endpoint of a server ConfigServer and refresh the configuration of all clients
-
The architecture in Figure 2 is obviously more suitable. The reasons why Figure 1 is not suitable are as follows
- It breaks the single responsibility of microservices, because microservices are business modules and should not undertake the responsibility of configuration refresh
- It breaks the equivalence of micro service nodes
- There are certain limitations. eg: when migrating a microservice, its network address often changes. At this time, if you want to refresh automatically, you will add more modifications
3.3 add message bus support to the server of 3344 configuration center
Modify pom add dependency
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- Add message bus RabbitMQ support --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Modify yaml configuration
server: port: 3344 spring: application: name: cloud-config-center # Microservice name registered into Eureka server cloud: config: server: git: username: zhouzhxu password: zzx.@10092111 uri: https://github. com/zhouzhxu/springcloud-config. Git # git warehouse address on GitHub # uri: git@github.com:zhouzhxu/springcloud-config.git # Password free login is required # search for directory search-paths: - springcloud-config # Read branch default-label: master # rabbitmq related configuration rabbitmq: host: 47.107.124.79 port: 5672 username: admin password: admin eureka: instance: instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} # Set instance access address prefer-ip-address: true # Set the access path to display the ip address client: # Indicates that you are registered with Eureka Server. The default value is true register-with-eureka: true # Whether to retrieve your existing registration information from Eureka Server. The default value is true. # Single node doesn't matter. The cluster must be set to true to use load balancing with ribbon fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka # Exposed bus refresh configured endpoint management: endpoints: web: exposure: include: 'bus-refresh'
3.4 add message bus support to 3355 configuration center client
Modify pom add dependency
<!-- Add message bus RabbitMQ support --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Modify bootstrap yaml
server: port: 3355 spring: application: name: cloud-config-client cloud: # config client configuration config: label: master # Branch name name: config # Profile name profile: dev # Suffix uri: http://localhost:3344 # configuration center address # rabbitmq related configuration rabbitmq: host: 47.107.124.79 port: 5672 username: admin password: admin eureka: instance: instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} # Set instance access address prefer-ip-address: true # Set the access path to display the ip address client: # Indicates that you are registered with Eureka Server. The default value is true register-with-eureka: true # Whether to retrieve your existing registration information from Eureka Server. The default value is true. # Single node doesn't matter. The cluster must be set to true to use load balancing with ribbon fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka # Exposure monitoring endpoint management: endpoints: web: exposure: include: "*"
3.5 add message bus support to 3366 configuration center client
Modify pom add dependency
<!-- Add message bus RabbitMQ support --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Modify bootstrap yaml
server: port: 3366 spring: application: name: cloud-config-client cloud: # config client configuration config: label: master # Branch name name: config # Profile name profile: dev # Suffix uri: http://localhost:3344 # configuration center address # rabbitmq related configuration rabbitmq: host: 47.107.124.79 port: 5672 username: admin password: admin eureka: instance: instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} # Set instance access address prefer-ip-address: true # Set the access path to display the ip address client: # Indicates that you are registered with Eureka Server. The default value is true register-with-eureka: true # Whether to retrieve your existing registration information from Eureka Server. The default value is true. # Single node doesn't matter. The cluster must be set to true to use load balancing with ribbon fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka # Exposure monitoring endpoint management: endpoints: web: exposure: include: "*"
3.6 testing
Modify the configuration file on GitHub
Send a post request to the configuration center server
curl -X POST "http://localhost:3344/actuator/bus-refresh"
One send takes effect everywhere
Configuration center
http://localhost:3344/config-dev.yaml
client
Get the configuration information and find that it has been refreshed
One amendment, broadcast notice, takes effect everywhere
4. Spring cloud bus dynamically refreshes fixed-point notifications
I don't want to be notified in full, but I just want to be notified at a fixed point
Specify that a specific instance takes effect instead of all
Formula: http:ip: configuration center port / Actor / bus refresh / {destination}
/The bus refresh request is no longer sent to the specific service instance, but to the config server. And specify the service or instance that needs to send updated configuration through the destination parameter class
Case:
- We just want to refresh the cloud config client running on port 3355 as an example
Only 3355, not 3366 - curl -X POST "http://localhost:3344actuator/bus-refresh/cloud-config-clent:3355"
Notification summary