配置中心以及消息总线
一、SpringCloudConfig配置中心
1.介绍
在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config组件中,分两个角色,一是config server,二是config client。
Config Server是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个
环境下的配置,默认使用Git存储配置文件内容,也可以使用SVN存储,或者是本地文件存储。
Config Client是Config Server的客户端,用于操作存储在Config Server中的配置内容微服务在启动时会请求Config Server获取配置文件的内容,请求到后再启动容器。
2.服务端
创建配置中心微服务模块tensquare_config
pom依赖:
<!--配置中心_服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
yml配置文件
server:
port: 12000
spring:
application:
name: tensquare-config
cloud:
config:
server:
git:
uri: Gitee仓库地址
username: Gitee用户名
password: Gitee密码
eureka:
client:
service-url:
defaultZone: http://localhost:6868/eureka
instance:
prefer-ip-address: true
主启动类
package com.lsh;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author :LiuShihao
* @date :Created in 2020/11/4 2:48 下午
* @desc :
*/
//配置中心 server
@EnableConfigServer
@EnableEurekaClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class);
}
}
3.客户端
pom依赖
pom文件添加上配置中心客户端依赖
<!--配置中心客户端 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
bootstrap.yml
已经上传yml配置文件到Gitee仓库了,所以可以将本地的yml文件删除。
新建bootstrap.yml
文件
spring:
cloud:
config:
# 文件名
name: manager
# 分支名
label: master
# 配置中心微服务模块的地址
uri: http://127.0.0.1:12000
客户端启动类并不需要修改。
4.启动测试
新建仓库,将配置文件手动上传到Gitee仓库。
启动配置中心微服务模块和客户端模块,
当客户端服务启动后,会加载bootstrap.yml配置文件,去找配置中心服务,配置中心去远程仓库读取对应配置,返回给客户端服务。
二、SpringCloudBus消息总线
如果我们更新码云中的配置文件,那客户端工程是否可以及时接受新的配置信息呢?
我们现在来做一个测试,修改一下码云中的配置文件中mysql的端口,然后测试http://localhost:9001/label 数据依然可以查询出来,证明修改服务器中的配置并没有更新立刻到工程,只有重新启动程序才会读取配置。
那我们如果想在不重启微服务的情况下更新配置如何来实现呢? 我们使用SpringCloudBus来实现配置的自动更新.
BUS是如何做到能够在在修改配置文件后就更新本地服务中的配置文件呢?
原理解释:
其实是在每一个客户端配置一个监听器,监听谁?监听码云吗?(一个资本家)不现实…
它监听的是MQ(bus采用的RabbitMQ),当码云上的配置文件进行了修改,我们手动向MQ发送一个消息,那么客户端监听到MQ有消息,BUS就会自动重新编译一下配置文件.
1.服务端
pom依赖
在刚刚的配置中心模块加上消息总线的依赖
<!-- 消息总线 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
yml配置文件
在刚刚的配置中心模块的yml配置文件加上消息总线的配置和MQ的配置
server:
port: 12000
spring:
application:
name: tensquare-config
cloud:
config:
server:
git:
uri:
username:
password:
rabbitmq:
host:
port: 5672
username:
password:
#暴露触发消息总线的地址
#Postman-post请求测试 Url: http://localhost:12000/actuator/bus-refresh
management:
endpoints:
web:
exposure:
include: "*"
eureka:
client:
service-url:
defaultZone: http://localhost:6868/eureka
2.客户端
pom依赖
<!--消息总线-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<!-- 因为需要refresh接口刷新配置,所以需要加上actuator的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
bootstrap.yml
spring:
cloud:
config:
name: base
# profile: dev
label: master
uri: http://127.0.0.1:12000
bus:
enabled: true
trace:
enabled: true
客户端Controller
需要加上@RefreshScope
注解才能刷新成功。
@RefreshScope
@RestController
@RequestMapping("/base")
public class BaseController {
}
主启动类不变。
@EnableDiscoveryClient
@EnableEurekaClient
@SpringBootApplication
public class BaseApplication {
public static void main(String[] args) {
SpringApplication.run(BaseApplication.class);
}
/**
* 注入雪花算法
* @return
*/
@Bean
public IdWorker getIdWorkder() {
return new IdWorker(1,1);
}
}
3.测试
我在客户端Controller写了一个获取配置文件值的方法
yml配置文件:
Controller:
@Value("${SpringCloud.Config.value}")
public String value;
@GetMapping("/springCloudBusGetvalue")
public ResultObject getValue(){
return new ResultObject(true, StatusCode.OK,"消息总线",value);
}
请求http://localhost:9001/base/springCloudBusGetvalue
会获得配置文件中我们设置的值。
这样就可以测试我们修改配置文件的值后程序是否更新配置。
首先远程仓库yml配置文件设置的值是111
修改远程Gitee仓库配置文件信息,修改成222
使用Postman POST请求http://localhost:12000/actuator/bus-refresh
刷新
再次访问 ,值已经变成222
Bug SpringBoot与SpringCloud版本不兼容
SpringBoot-2.2.2.RELEASE整合SpringCloud-Hoxton.SR6中Bus消息总线组件版本不兼容问题
启动报错
原因是SpringBoot和SpringCloud的版本冲突了。
我使用的SpringBoot2.2.0和SpringCloudHoxton.SR4,
解决办法:
SpringBoot版本换成2.2.2.RELEASE,SpringCloud版本换成Hoxton.SR6,即可启动成功!
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Bug 消息总线手动刷新后 修改配置 无效
当修改远程Gitee仓库的配置文件后,使用http://localhost:12000/actuator/bus-refresh
手动刷新,日志显示 重新刷新了配置文件,但是无效,调用方法获取到的仍是原来的值。
解决办法:
在客户端的Controller上加注解:@RefreshScope
用postman执行了/bus/refresh接口之后,能看到config-client服务下面打印出的日志,明显能看到
Received remote refresh request. Keys refreshed [people.name, people.age] 确实已经获取到刷新信息了,那为什么我请求接口还是没有任何变化呢,后来尝试加了
@RefreshScope注解之后,成功完成刷新。。。。
大概原因大概是这样 :因为其他客户接收到广播后,会通过这个注解找属性进行刷新值;归根到底就是应用仅仅只是接收到广播说“你该刷新了”,然后进行spring cloud的/refresh操作,然后通过@RefreshScope注解寻找对应属性进行重新赋值
springcloud bus中踩过的坑