文章目录
- 一.概念
- 二.服务端连接git
- 1.导入依赖
- 2.配置文件
- 3.启动类
- 4.效果
- 三.客户端从服务端3344获取配置信息
- 1.导入配置
- 2.配置文件
- 3.客户端调用接口
- 4.启动类
- 5.效果
- 四.分布式配置动态刷新
- 1.导入依赖
- 2.修改客户端配置文件
- 3.客户端controller层新增一个注解@RefreshScope
- 4.发送Post请求刷新3355
- 5.效果
- 五.Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新
- 1.设计思想
- 2.什么是总线?
- 3.实现配置的动态刷新
- 4.定点通知
一.概念
对于微服务系统来说,一个系统内可能有几十个服务,然后可能会启动上百个实例。
可能其中十个服务都需要连接DB,二十个服务都需要连接Redis或者MQ。如果把DB连接url及用户名密码分写配置到各个服务的application.yml文件中,将会是一件十分枯燥和容易出错的事情,而且如果DB库更换用户名了话,需要各个服务一个一个去修改然后重启,显然是非常不合理的。
在微服务系统中,把配置统一放到配置中心服务,然后各个服务到配置中心拉取配置。当配置修改后,可以通过bus总线通知各个服务,使其从配置中心拉取修改后的配置。
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去;client通过接口获取数据、并依据此数据初始化自己的应用.
二.服务端连接git
1.导入依赖
<!--springcloud-config-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
2.配置文件
server:
port: 3344
spring:
application:
name: springcloud-config-server
cloud:
config:
server:
git:
uri: https://gitee.com/wang_shi_yong/springcloud-config.git #注意:这里是要https的连接方式。不是ssh的
3.启动类
@SpringBootApplication
@EnableConfigServer //
public class Config_server_3344 {
public static void main(String[] args) {
SpringApplication.run(Config_server_3344.class,args);
}
}
4.效果
通过config-server可以连接到git,访问其中的资源及配置
三.客户端从服务端3344获取配置信息
1.导入配置
<!--不带server了,说明是客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
2.配置文件
application.yml
#这是用户级别的配置
spring:
application:
name: springcloud-config-client-3355
bootstrap.yml
#云端拿东西用bootstrap.yml
#这是系统级别的配置,而application.yml是用户级别的配置
spring:
cloud:
config:
uri: http://localhost:3344
name: config-client #注意:这里不需要加后缀
profile: test #选这个配置的dev环境
label: master #选择分支
3.客户端调用接口
@RestController
public class configClientController {
@Value("${spring.application.name}")
private String applicationName; //获取微服务名称
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaServer; //获取Eureka服务
@Value("${server.port}")
private String port; //获取服务端的端口号
@RequestMapping("/config")
public String getConfig(){
return "applicationName:"+applicationName+
" eurekaServer:"+eurekaServer+
" port:"+port;
}
}
4.启动类
@SpringBootApplication
public class config_client_3355 {
public static void main(String[] args) {
SpringApplication.run(config_client_3355.class,args);
}
}
5.效果
四.分布式配置动态刷新
Linux运维修改GitHub上的配置文件内容做调整,刷新3344发现ConfigServer配置中心立刻响应,刷新3355发现ConfigServer客户端没有任何响应,除非3355自己重启或者重新加载才能响应,为了避免每次更新配置都要重启客户端微服务3355,需要在客户端设置分布式配置动态刷新。
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.修改客户端配置文件
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
3.客户端controller层新增一个注解@RefreshScope
@RestController
@RefreshScope
public class ConfigClientController
{
@Value("${spring.application.name}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo()
{
return configInfo;
}
}
4.发送Post请求刷新3355
curl -X POST “http://localhost:3355/actuator/refresh”
5.效果
成功实现了客户端3355刷新到最新配置内容,避免了服务的重启
但是还是存在问题~
- 假如有多个微服务客户端3355/3366/3377。。。。。。+
- 每个微服务都要执行一次post请求 ,手动刷新?
- 可否广播,一次通知,处处生效?
- 我们想大范围刷新呢?
这时需要消息总线
五.Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新
1.设计思想
第一种设计思想图示:
第二种设计思想图示:
第一种设计思想不合适的原因:
2.什么是总线?
3.实现配置的动态刷新
创建两个客户端
步骤
- 引入依赖
<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--config-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 配置文件bootstrap.xml
server:
port: 3355
spring:
application:
name: config-client
cloud:
#Config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
- 客户端启动类
@EnableEurekaClient
@SpringBootApplication
public class ConfigClientMain3355
{
public static void main(String[] args) {
SpringApplication.run(ConfigClientMain3355.class, args);
}
}
- 控制器接口
@RestController
@RefreshScope
public class ConfigClientController
{
@Value("${spring.application.name}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo()
{
return configInfo;
}
}
服务端
- 1.引入依赖
<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 服务端配置文件application.xml
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://gitee.com/wang_shi_yong/springcloud-config.git #git@github.com:hhf19906/springcloud-config.git
search-paths:
- springcloud-config
label: master
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
- 服务端启动类
@SpringBootApplication
@EnableConfigServer
public class ConfigCenterMain3344
{
public static void main(String[] args) {
SpringApplication.run(ConfigCenterMain3344.class, args);
}
}
测试
- 修改Github上配置文件增加版本号
- 实现一次修改,广播通知,处处生效
4.定点通知
不想全部通知,只想定点通知
公式:http://localhost:配置中心的端口号/actuator/bus-refresh/{destination}
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"