分布式系统面临的问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务粒度相对较小,因此系统会出现大量服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
SpringCloud Config是什么?
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,为各个不同微服务应用的所以环境提供一个中心化的外部配置。
SpringCloud Config分为服务端和客户端两个部分。
服务端也称为分布式配置中心,它是个独立的微服务应用。用来配置服务器并为客户端提供获取配置信息。
客户端通过指定配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样有助于对环境配置进行版本管理。
SpringCloud Config服务端配置
- 新建Module模块cloud-config-center-3344
- pom
<!--eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--config服务端--->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- yaml
server:
port: 3344
spring:
application:
name: config-center
cloud:
config:
server:
git:
uri: https://github.com/chuxuyang/SpringCloud-Config.git #github仓库地址
search-paths:
- SpringCloud-Config #仓库文件夹目录
label: master
#eureka配置
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
instance:
prefer-ip-address: true
ip-address: config
- 主启动类
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class ConfigMain3344 {
public static void main(String[] args) {
SpringApplication.run(ConfigMain3344.class,args);
}
}
- 读取配置规则
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
SpringCloud Config客户端配置
- 新建Module模块cloud-config-client-3344
- pom依赖
<!--eureka--->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--config客户端--->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- yaml(必须bootstrap.yml)
bootstrap.yml加载优先于application.yml
server:
port: 3355
spring:
application:
name: config-client
cloud:
config:
label: master #github分支名称
name: config #文件名称
profile: dev #文件后缀 config-dev
uri: http://localhost:3344
#eureka配置
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
- 主启动类
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain {
public static void main(String[] args) {
SpringApplication.run(ConfigClientMain.class,args);
}
}
- 新建ConfigClientController.java
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfig(){
return configInfo;
}
}
- 启动服务,并访问http://localhost:3355/configInfo
Config客户端之动态刷新
经过config客户端和服务端的配置后,当修改github的配置信息时,客户端需要重启服务才能获取最新配置信息。
如何实现客户端动态刷新?
- 客户端pom文件需引入actuator监控
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 修改yaml,暴露监控端口
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
- 业务类Controller加
@refreshScope
@RestController
@RefreshScope//配置文件自动刷新
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfig(){
return configInfo;
}
}
经过以上配置后,只需发送post请求即可刷新客户端,不需要重启服务。
SpringCloud Bus动态刷新全局广播
- 新建Module模块cloud-config-client-3366(仿照3355)
- RabbitMQ环境配置
- config服务端和客户端pom引入bus依赖
<!--bus+rabbitmq--->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 客服务端yaml文件修改
server:
port: 3344
spring:
application:
name: config-center
rabbitmq:
host: 192.168.74.129
port: 5672
username: guest
password: guest
#暴露bus刷新端点
management:
endpoints:
web:
exposure:
include: "bus-refresh"
- 客户端yaml文件修改
spring:
application:
name: config-client
cloud:
config:
label: master #github分支名称
name: config #文件名称
profile: dev #文件后缀 config-dev
uri: http://localhost:3344
rabbitmq:
host: 192.168.74.129
port: 5672
username: guest
password: guest
经过以上配置后,只需发送post请求,利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,从而刷新所有客户端配置
也可以发送post请求http://localhost:3344/actutor/bus-refresh/{destination}
通知到具体实例