Spring Cloud Bus 可以非常容易地搭建起消息总线,典型的应用场景就是:配合 Spring Cloud Config 实现微服务应用配置信息的动态更新。
目标
实现动态配置变更。
创建一个 config server,2个 config client,修改配置后,访问 config client 1 的 /bus/refresh,实现config client 1、2 的自动更新配置。
步骤
创建一套干净的 config server 和 client,使配置中心和客户端应用都正常运行。
启动 RabbitMQ。
修改 server 和 client,使其支持 bus。
测试,验证配置自动更新是否生效。
准备 git
bus-config-client.properties
from=git-default-1
提交到 git。
创建 config server
start.spring.io 上创建应用 bus-config-server。
pom.xml
<?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.example</groupId>
<artifactId>bus-config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>bus-config-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR5</spring-cloud.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>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</project>
启动类开启 configserver
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class BusConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(BusConfigServerApplication.class, args);
}
}
application.properties 中添加 git 的连接信息:
spring.application.name=bus-config-server
server.port=7001
spring.cloud.config.server.git.uri=https://gitee.com/xxx/springcloud-config
spring.cloud.config.server.git.searchPaths=config-repo
spring.cloud.config.server.git.username=xxx
spring.cloud.config.server.git.password=xxx
启动应用:
$ mvn spring-boot:run
访问 http://localhost:7001/bus-config-client/default/master,应显示配置信息。
创建 config client
start.spring.io 上创建应用 bus-config-client。
pom.xml
<?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.example</groupId>
<artifactId>bus-config-client1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>bus-config-client1</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR4</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</project>
bootstrap.properties 中配置 config server 信息:
spring.application.name=bus-config-client
spring.cloud.config.profile=default
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:7001/
application.properties
server.port=8070
创建控制器 TestController:
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;
@RestController
public class TestController {
@Value("${from}")
private String hello;
@RequestMapping("/hello")
public String from() {
return this.hello;
}
}
启动项目:
$ mvn spring-boot:run
访问 http://localhost:8070/hello,应显示配置项“from”的值:git-default-1。
没问题之后,复制一个此项目为 bus-config-client2,端口改为 8071,启动项目,访问 http://localhost:8071/hello,也应显示:git-default-1。
添加 bus 支持
3个项目的 pom.xml 中都添加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
用于添加对 bus 和 refresh 的依赖。
3个项目的 application.properties 中都添加:
management.security.enabled=false
用于关闭 actuator 的安全验证。
2个client项目的 TestController 中添加类注解:
@RefreshScope
用于对 @Value 自动刷新。
2个client项目的 application.properties 中都添加:
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
用于连接 rabbitmq。
重新启动 bus-config-server,启动完成后,重新启动2个client项目。
验证
修改配置文件 bus-config-client.properties
from=git-default-2
提交。
使用POST方式访问 http://localhost:8070/bus/refresh,看2个client项目的控制台输出信息,可以看到重新加载的日志。
访问 http://localhost:8070/hello 和 http://localhost:8071/hello,会都显示:git-default-2,完成了自动更新。