缘起
在分布式系统中,由于服务数量非常多,配置文件分散在不同的微服务项目中,管理不方便。为了方便配置文件集中管理,需要分布式配置中心组件。在Spring Cloud中,提供了Spring Cloud Config,它支持配置文件放在配置服务的本地,也支持放在远程Git仓库(GitHub、码云)。
使用Spring Cloud Config配置中心后的架构如下图:
创建远程配置仓库
配置文件的命名方式:{application}-{profile}.yml 或 {application}-{profile}.properties
application为应用名称profile用于区分开发环境,测试环境、生产环境等如userservice-dev.yml,表示用户微服务开发环境下使用的配置文件。
这里将userservice工程的配置文件application.yml文件的内容复制作为user-dev.yml文件的内容。
创建配置服务
添加依赖
<?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">
<parent>
<artifactId>springcloudparents</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>configserver</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--<executions>
<execution>
<phase>none</phase>
</execution>
</executions>-->
</plugin>
</plugins>
</build>
</project>
创建启动类
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
此处要注明的是需要添加@EnableConfigServer配置类
创建配置类
server:
port: ${port:12000}
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: https://gitee.com/xueshanfeitian/feitianconfig.git
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
需要从码云上拉取地址,所以我们需要添加码云配置仓库地址。
测试后配置中心搭建成功
改造userservice
userservice需要改造yaml配置文件
spring:
cloud:
config:
#要与配置仓库中的配置文件application的名字保持一致
name: userservice
# 要与仓库中的profiles
profile: dev
# 要与仓库中的配置文件所属的分支号保持一致
label: master
discovery:
enabled: true
service-id: configserver
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
访问userservice端口:
springbus
上述案例存在的问题
当修改配置远程仓库中的配置文件时,配置文件更新的实时性出现问题,每次服务都得重启才能获取最新配置文件,如何解决这一问题,我们将采用一种全新的技术架构来解决此问题。
架构的改进
Spring Cloud Bus是用轻量的消息代理将分布式的节点连接起来,可以用于广播配置文件的更改或者服务的监控管理。也就是消息总线可以为微服务做监控,也可以实现应用程序之间相互通信。 Spring Cloud Bus可选的消息代理有RabbitMQ和Kafka。
Spring Cloud Bus将git仓库的配置文件更新,在不重启系统的情况下实现及时同步到各个微服务。
springcloud bus使用
启动rabbitmq
修改configserver依赖
在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>
修改配置文件
需要接入rabbitMQ的地址
server:
port: ${port:12000}
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: https://gitee.com/xueshanfeitian/feitianconfig.git
# 配置rabbit信息
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
management:
endpoints:
web:
exposure:
# 暴露触发消息总线地址
include: bus-refresh
改造userservice
修改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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改配置文件
spring:
cloud:
config:
#要与配置仓库中的配置文件application的名字保持一致
name: userservice
# 要与仓库中的profiles
profile: dev
# 要与仓库中的配置文件所属的分支号保持一致
label: master
discovery:
enabled: true
service-id: configserver
# 配置rabbit信息
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
修改更新作用范围
@RestController
@RequestMapping("/userController")
@RefreshScope
public class UserController {
@Autowired
private UserService userService;
@Value("${test.name}")
private String name;
@RequestMapping("/findById/{id}")
public User findById(@PathVariable Long id){
System.out.println("------the name is ---------"+name);
return userService.findById(id);
}
@RequestMapping("/queryById/{id}")
public User queryById(@PathVariable Long id){
System.out.println("------the name is ---------"+name);
return userService.queryById(id);
}
}
测试
启动顺序
测试结果
发送postman请求更新配置文件
说明配置文件在线更新成功。