1.前言
一提到微服务,那么离不开的就是配置中心,而对于多个服务共用的配置我们总希望有一个配置中心进行保存。Springcloud提供的Spring Cloud Config
就为我们提供了这个能力,下边我们从零开始搭建一个分布式配置中心。
2.分布式配置中心搭建
服务 | 端口 | 作用 |
---|---|---|
eureka-service | 8761 | 注册中心 |
config-service | 8888 | 配置中心服务端 |
producer-client | 9001 | 客户端 |
producer-client | 9002 | 客户端 |
- 码云上创建配置文件件保存配置文件
注意:配置文件名称需根据规则进行设置:如
config-client-dev.yml
,其中config-client
:表示定义的服务名,dev
:表示激活何种模式,主要针对不同的场景设置不同的配置文件,如生产、开发、测试等环境
- 创建注册中心
eureka-service
- 创建分布式配置中心服务端
(1)引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(2) 配置application.yml
在此以码云为例进行配置,大家也可以使用github账户或svn账号配置均可
spring:
cloud:
config:
server:
git:
uri: https://gitee.com/xxx/spring-cloud-config.git
search-paths:
- config
default-label: master
username: admin
password: admin
配置说明:
配置 | 说明 |
---|---|
uri | git中配置文件仓库地址 |
search-paths | 配置文件夹 |
default-label | 配置文件所在分支 |
username | 码云用户名 |
password | 码云密码 |
(3)启动配置中心
访问http://localhost:8888/config-producer-dev.yml
出现如下界面表示配置中心服务端配置成功,下图中userAge=22即为第一步中配置文件配置信息
- 创建分布式配置中心客户端
(1)引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
注意:一定要引入spring-boot-starter-web
依赖,否则配置不成功
(2)配置bootstrap.yml
spring:
cloud:
config:
name: config-producer
label: master
profile: dev
discovery:
service-id: config-server
enabled: true
fail-fast: false
retry:
max-attempts: 6
配置说明:
配置 | 说明 |
---|---|
spring.cloud.config.name | 表示配置文件中配置的前缀名称,本例中配置文件在git中名为config-producer-dev.yml |
spring.cloud.config.profile | 配置选择那一个配置文件,根据配置文件名选择 |
spring.cloud.config.label | 选择分支 |
spring.cloud.config.discovery.service-id | 表示配置中心服务端名称 |
spring.cloud.config.discovery.enabled | 表示可发现配置中心 |
spring.cloud.config.fail-fast | 表示是否快速失败 |
spring.cloud.config.retry.max-attempts | 表示失败重试次数 |
(3)启动测试
当启动客户端时,获取配置文件中变量 ,则能正常获取到配置文件变量值表示配置中心客户端配置成功
通过上述配置,我们在启动时能正常获取配置文件中的值,但当配置文件中值被修改时,我们此时只能通过重启服务的方式来获取配置文件中的值 ,在实际生产中我们不可能每次修改配置文件就重启服务,因此我们需要下边的属新配置文件。
3.手动刷新配置
-客户端增加服务监控依赖
<!-- actuator监控中心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 客户端修改配置文件
bootstrap.yml
management:
endpoints:
web:
exposure:
include: "*"
- 获取配置文件处类上增加
@RefreshScope
@RestController
@RefreshScope
public class ProducerController {
@Value("${userAge}")
private String userAge;
@GetMapping("/test1")
public String test1(){
return userAge;
}
}
- 当修改配置文件后,需手动执行如下
POST
请求,ip及端口为客户端配置端口
$ http://localhost:9001/actuator/refresh
通过上述配置,我们修改完配置中心配置后,在手动请求一次上述更新接口,则会将服务获取到的配置进行更新。但上述手动刷新配置存在问题,如果服务有成百上千个,那么我们就要对每个服务进行刷新,显然是不可取的,因此我们需要配置Bus消息总线进行动态刷新配置
4.消息总线动态刷新配置
- 配置中心服务端、客户端均增加消息总线依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 配置文件中增加
rabbitmq
配置,默认为本机mq
,且账户名密码均为guest
,mq
可选择rabbitmq
和kafka
spring:
rabbitmq:
host: 192.168.1.100
port: 5672
username: admin
password: admin
- 配置刷新
management:
endpoints:
web:
exposure:
include: bus-refresh
- 启动测试
上述配置完成后,我们启动多个客户端,同时修改配置文件,当我们访问客户端请求时发现配置依然没有更新,我们还需要手动执行如下请求:
$ http://localhost:9001/actuator/bus-refresh
当执行完上述请求后,我们在访问启动的两个客户端发现配置已经更新,虽然结合Bus消息总线进行消息刷新也需要手动触发一次,但是触发一次就已经将配置更新至所有服务,因此此种方式也是可取的。至此,我们的分布式配置中心搭建以及整合Bus进行配置动态刷新已经整合完毕。
5.消息总线刷新配置原理解析
- 当配置搭建完毕,启动服务时,我们登录
rabbitmq
发现会多一个exchange
,同时启动的客户端均有一个队列绑定该exchange
。
- 当配置中心文件进行修改后,我们手动发送一次刷新请求,实质以消息形式发送至上述构建的
exchange
中。 - 当消息发送至
exhange
中时,根据路由键路由至绑定的队列中,由于路由键为通配符#
表示任何请求均发送至队列中,通过一次请求刷新所有服务配置。