为什么要统一管理微服务配置
对于Spring Boot应用,我们可以将配置内容写入application.yml
,设置多个profile,也可以用多个application-{profile}.properties
文件配置,并在启动时指定spring.profiles.active={profile}
来加载不同环境下的配置。
在Spring Cloud微服务架构中,这种方式未必适用,微服务架构对配置管理有着更高的要求,如:
- 集中管理:成百上千(可能没这么多)个微服务需要集中管理配置,否则维护困难、容易出错;
- 运行期动态调整:某些参数需要在应用运行时动态调整(如连接池大小、熔断阈值等),并且调整时不停止服务;
- 自动更新配置:微服务能够在配置发生变化是自动更新配置。
以上这些要求,传统方式是无法实现的,所以有必要借助一个通用的配置管理机制,通常使用配置服务器来管理配置。
Spring Cloud Config分为Config Server和Config Client两部分,为分布式系统外部化配置提供了支持。 Spring Cloud Config非常适合Spring应用程序,也能与其他编程语言编写的应用组合使用。
微服务在启动时,通过Config Client请求Config Server以获取配置内容,同时会缓存这些内容。
POSTMAN或CURL等工具直接来访问到我们的配置内容了。访问配置信息的URL与配置文件的映射关系如下:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
上面的url会映射{application}-{profile}.properties
对应的配置文件,其中{label}
对应Git上不同的分支,默认为master。我们可以尝试构造不同的url来访问不同的配置内容,比如,要访问master分支,config-client应用的dev环境,就可以访问这个
访问路径:http://localhost:4040/config-client/dev/master
访问路径:
- config-client ---> label
- dev
- master
引入jar包:
compile group: 'org.springframework.cloud', name: 'spring-cloud-config-server', version: '2.2.3.RELEASE'
配置启动类:
package com.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args){
SpringApplication.run(ConfigServerApplication.class);
}
}
配置文件:
server:
port: 4040
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/alfredhua/spring-cloud-config-repository.git
配置config-client
package com.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClientApplication {
public static void main(String[] args){
SpringApplication.run(ConfigClientApplication.class);
}
}
package com.server;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope
@RestController
public class TestController {
@Value("${info.from}")
private String from;
@RequestMapping("/from")
public String from() {
return this.from;
}
}
spring.application.name:对应配置文件规则中的{application}部分
spring.cloud.config.profile:对应配置文件规则中的{profile}部分
spring.cloud.config.label:对应配置文件规则中的{label}部分
spring.cloud.config.uri:配置中心config-server的地址
spring:
application:
name: config-client
cloud:
config:
uri: http://localhost:4040/
profile: dev
label: master
discovery:
service-id: config-server
server:
port: 2001
配置刷新
- 重新启动config-clinet,访问一次
http://localhost:2001/from
,可以看到当前的配置值 - 修改Git仓库
config-client/config-client-dev.yml
文件中from
的值 - 再次访问一次
http://localhost:2001/from
,可以看到配置值没有改变 - 通过POST请求发送到
http://localhost:2001/refresh
,我们可以看到返回内容如下,代表from
参数的配置内容被更新了