Chapter2 消息总线ConfigClient配置自动刷新
Spring Cloud Bus:
Spring Cloud Bus提供了批量刷新配置的机制,它使用轻量级的消息代理(例如RabbitMQ、Kafka等)连接分布式系统的节点,这样就可以通过Spring Cloud Bus广播配置的变化或者其他的管理指令。使用Spring Cloud Bus后的架构如图所示。
准备工作:
需要安装rabbitMQ,安装rabbitMQ的详情请参考:https://blog.csdn.net/qq_35098526/article/details/80009424这篇文章主要讲Windows下的安装过程。
环境搭建
创建三个模块:
eureka-server eureka服务注册中心
config-server 配置中心服务端
config-client 配置中心客户端
1. eureka-server 模块pom文件配置如下,这里跟第一章节一样 ,不多说。
<?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.harry</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-server</name>
<description>EUREKA 服务注册中心</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.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>Finchley.M9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
2. config-server 配置中心服务端pom配置,这里引入了spring-cloud-starter-bus-amqp。
<?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.harry</groupId>
<artifactId>config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>config-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.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>Finchley.M9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
application.yml 配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8889/eureka/
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://gitee.com/honghh/spring-cloud-config # 配置git仓库地址
searchPaths: config-doc # 配置仓库路径
# username: # 访问git仓库的用户名
# password: # 访问git仓库的用户密码
# label: #配置仓库的分支
server:
port: 8989
在application.yml可以看到引入了git仓库地址,如果仓库是私有的,需要输入访问的账号和密码,这个地址是我自己测试用的,是公开的,可以不输入账号密码。searchPaths:config-doc# 配置仓库路径如果仓库路径是根目录则不需要写这个,如果是多级目录,可以写成A/B/C格式。
2. config-client 配置中心客户端这里需要注意pom文件中引入了spring-cloud-starter-bus-amqp,spring-boot-starter-actuator,spring-retry
<?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.harry</groupId>
<artifactId>config-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>config-client</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.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>Finchley.M9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</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-test</artifactId>
<scope>test</scope>
</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
bootstrap.yml 配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8889/eureka/
server:
port: 8881
spring:
application:
name: config-client
cloud:
config:
label: master
profile: dev
discovery:
enabled: true
service-id: config-server
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#management:
# security:
# enabled: false #spring boot1.5.x 版本配置
management:
endpoints:
web:
exposure:
include: bus-refresh
这里写入rabbitMQ的配置和management的配置,我们可以看到有一段注释的代码,解析看下面注意有坑①。
启动项目
依次启动eureka-server、confg-cserver,启动两个config-client,端口为:8881
1.访问http://localhost:8881/hi浏览器显示:
2这时我们去代码仓库将config-client-dev.properties下的foo的值改为“foo version 4”,即改变配置文件foo的值。如果是传统的做法,需要重启服务,才能达到配置文件的更新。此时,我们只需要发送post请求:http://localhost:8881/bus/refresh,你会发现config-client会重新读取配置文件。可以看到控制台打印日志如图。注意有坑 ①
3. 再次请求http://localhost:8881/hi
到这里操作就已经完成。接下来我们讲一下遇到的问题
注意有坑
① 上面提到请求 http://localhost:8881/bus/refresh但是你在运行的时候遇到报404的错误
图5.1
图5.2
首先,你要确认是post请求,如图5.1是get请求,是会报404的错误的
但是图5.2中用的是post请求为什么还会报错
这里就是我所说的坑看项目中的pom文件我用的是spring boot 2.0.1.RELEASE版本,查资料看到一篇文章 https://ask.csdn.net/questions/684123
详情如下:
SpringBoot2.0Config客户端自动刷新时没有/bus/refresh端点
Spring Cloud ConfigClient的配置自动刷新
目前的博客和视频都是Spring Boot1.5.x的,安装rabbitmq,导入依赖,配置yml,添加@RefreshScope,启动Config client时日志都会打印出/bus/refresh这个端口,但是到spring boot2.0就不再打印这个端口,也无法访问。即使yml配置暴露actuator的所有端口,也就只有/actuator/refresh这个端口(这个端口是只更新一个的)。
请问Spring boot 2.0如何实现Config Client自动刷新配置
Spring boot 2.0的改动较大,/bus/refresh全部整合到actuador里面了,所以之前1.x的management.security.enabled全部失效,不适用于2.0
适用于2.0的配置是这样的:
management:
endpoints:
web:
exposure:
include: bus-refresh
另外注解
@RefreshScope
需要在配置的页面加上,就是说附带@Value的页面加上此注解
请求刷新的页面由原来1.5.x的localhost:8888/bus/refresh
变成:http://localhost:8888/actuator/bus-refresh
注意:config-server和config-client的配置都得加上
management:
endpoints:
web:
exposure:
include: bus-refresh
所以这就是上面为什么这样改的原因,执行刷新的的请求为:
http://localhost:8881/actuator/bus-refresh
下载地址:
代码我已同步到码云git :https://gitee.com/honghh/spring-cloud-config