分布式配置中心SpringCloud Config
微服务面临的问题:可以看到,每个微服务都需要一个配置文件,并且,如果有几个微服务都需要连接数据库,那么就需要配4次数据库相关配置,并且当数据库发生改动,那么需要同时修改4个微服务的配置文件才可以,所以有了springconfig配置中心
能力:
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置+
- 将配置信息以REST接口的形式暴露,post、curl访问刷新均可
实现配置中心服务端
-
首先在github上建一个远程项目,存放config配置文件,并添加一个config.info的配置项
-
建模块
cloud-config-center-3344
-
导依赖(部分)
<!--config server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 写yml文件
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://github.com/kzj666/springcloud-config.git #git仓库名字
search-paths:
- springcloud-config #搜索目录
label: master #分支名
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka, http://eureka7002.com:7002/eureka
- 主启动类加上
@EnableConfigServer
注解 - 启动测试
http://localhost:3344/master/config-dev.yml
【格式为:http://localhost:3344/分支名/文件名】
实现配置中心客户端
相当于【配置中心服务端3344】就从github上读取配置,但是【配置中心客户端3355】就从你3344上读取
- 建模块
cloud-config-client-3355
- 导依赖(关键依赖)
<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<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>
- 创建
bootstrap.ym
l文件【bootstrap文件是系统级的,比用户级的application文件的优先级更高,更先加载且不会被覆盖】
server:
port: 3355
spring:
application:
name: config-client
cloud:
#config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: prod #读取后缀名称 上述3个综合:读取master分支上config-dev.yml的配置文件
uri: http://localhost:3344 #配置中心地址
#http://localhost:3344/master/config-dev.yml
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka, http://eureka7002.com:7002/eureka
这四个整合在一起的意思是:客户端会读取http://localhost3344/master/config-prod.yml
4. 主启动类增加@EnableEurekaClient
注解,将3355服务注册到Eureka中去
5. 添加Controller,Rest风格实现调用
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("configInfo")
public String GetConfigInfo(){
return configInfo;
}
}
- 启动测试,访问http://localhost:3355/configInfo,可以访问到配置文件中的confi.info属性的值。
但是这种方式,会导致github上配置的更新,只能马上被配置中心服务端3344感知到,而配置中心客户端3355只能重启才能服务感知到这个改变
如何实现客户端动态刷新(其实也是半自动)
- 确保配置中心客户端3355有actuator的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 添加配置
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
- 在控制类上添加
@RefreshScope
注解 - 启动,测试github上配置的修改,在配置中心客户端3355能否实时更新,发现还是不可以。。。
- 因为还需要多一步,doc窗口执行以下curl的POST命令
curl -X POST "http://localhost:3355/actuator/refresh"
通知3355
具体流程就是:
①我们启动好服务后;②运维人员,修改了配置文件,然后发送一个post请求通知3355;③3355就可以获取最新配置文件
结合消息总线实现配置的一次通知全部客户端自动更新
上面那种方式意味着需要通知所有的配置客户端,虽然可以写一个脚本去执行,但是还有更牛逼的方式。
- 两种方式:(第二种方式更佳)
一是Bus直接通知给其中一个客户端,由这个客户端开始蔓延,传播给其他所有客户端
二是通知给配置中心的服务端,由服务端广播给所有客户端
Bus只支持两种消息代理RabbitMQ
和Kafka
RabbitMQ的安装:
https://www.bilibili.com/video/BV1pa4y1x7Kc?p=3
双击启动RabbitMQ,访问localhost:15672
,账号密码都为guest
采用第二种方式
- 以3355为模板新建一个3366
- 在3344中添加mq相关依赖
<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 在yml中添加相关配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#暴露bus刷新配置的端点
management:
endpoints:
web:
exposure:
include: "bus-refresh"
- 给3355和3366客户端添加消息总线支持,即上述步骤3的添加pom依赖和yml配置操作
- 启动测试,github上修改配置,curl命令刷新3344,
curl -X POST "http://localhost:3344/actuator/bus-refresh"
,查看3355和3366访问到的配置是否更新
原理:所有客户端都监听了一个rabbitMq的topic,我们将信息放入这个topic,所有客户端都可以送到,从而实时更新
实现定点通知
比如只通知3355,不通知3366
curl -X POST "http://localhost:3355/actuator/bus-refresh/config-client:3355"
实际上就是通过微服务的名称+端口号进行指定从而实现定点通知