简介
之前我们的配置都是放在项目的classpath目录下的,每次要修改某个模块的参数,就得去这个模块修改它的配置文件,这种方式对运维来说简直是灾难,尤其是微服务架构大行其道的今天
所以我们需要一种全新的方式去管理这些配置文件,spring cloud为我们提供了spring cloud config组件去做这些事。
我们现在只需要把配置文件上传到git或svn上。spring cloud config分为config server和config client,config server专门用来读取git/svn上的配置文件。config client集成在我们的项目里面,去config server读取这些配置。以后就可以把要经常改动的配置放到网上,直接打开浏览器就可以轻松管理上百个配置文件了
快速上手
看源码的 config 模块
因为我这项目本身就是放在git上管理的,所以直接在项目根路径新建个gitconfig目录,用来存放配置文件,然后push到git上就能访问了
搭建config server,这一步比较容易,不需要写什么代码
新建config-server模块,添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
在启动类上添加@EnableConfigServer注解
添加配置
server.port=8081
eureka.client.service-url.defaultZone=https://localhost:8080/eureka
spring.application.name=config-server
# config server的配置
# git路径
spring.cloud.config.server.git.uri=https://e.coding.net/codox/springcloud-learning.git
# 根路径下的哪个目录
spring.cloud.config.server.git.search-paths=gitconfig
# 那个分支
spring.cloud.config.label=master
搭建config client
新建config-client模块,添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
在resources目录再添加个bootstrap.properties文件,配置config server的uri
bootstrap.properties
# 如果在application里面配置,启动的时候也会直接去连接8888端口
# 如果config server不在8888端口,config client会报错,
# 因为bootstrap比application早加载,所以在bootstrap里面配置就可以解决这个问题
spring.cloud.config.uri=https://localhost:8081
application.properties
server.port=8082
eureka.client.service-url.defaultZone=https://localhost:8080/eureka
spring.application.name=config-client
spring.cloud.config.profile=dev
配置文件名就是${spring.application.name}-${spring.cloud.config.profile}.properties
或者yml。所以在gitconfig目录创建个config-client-dev.properties文件,用来保存配置
config-client-dev.properties
name=lisi
age=20
上传到git服务器
创建个controller,用来测试是否将git上的配置注入成功
@RestController
public class ReaderConfigController {
@Value("${name}")
private String name;
@Value("${age}")
private String age;
@RequestMapping("/read-config")
public String readConfig() {
return String.format("读取的name是%s, age是%s", name, age);
}
}
启动eureka,config server,config client
访问8082端口
发现读取成功
手动刷新config client的配置
如果修改了git上的配置,想要同步到config client上,那么需要在config client引入spring-boot-starter-actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在application.properties添加配置
management.endpoints.web.exposure.include=refresh
在注入配置的Bean对象上加上@RefreshScope注解
@RestController
@RefreshScope
public class ReaderConfigController {
...
}
修改git上的配置之后,需要访问config client端的/actuator/refresh接口,注意只能是POST请求
2.x版本改动很大,1.x的教程大多都是说直接访问/refresh接口,配置也和2.x不一样,我这里用的是2.x,1.x就不细说了。
将config-client-dev.properties name修改成zhangsan,然后重新push
name=zhangsan
age=20
没有访问/actuator/refresh接口之前,config client的name还是lisi,现在用postman刷新一下
刷新成功,可以看到,还返回了哪些属性是被修改过的
再次刷新页面,可以看到,注入的name变了
集成Spring Cloud Bus自动刷新所有配置
原理是通过向config server发送一条消息,然后config server把这条消息传到ribbitmq中,可以根据路由键通知指定部分的config client,默认通知所有的客户端
Config Server端配置
在config server添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
添加配置
# 启用刷新接口
management.endpoints.web.exposure.include=bus-refresh
# ribbitmq配置
spring.rabbitmq.host=192.168.159.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
Config Client端配置
客户端也需要配置ribbitmq,才能接收消息。添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
ribbimq配置,和config server一样
spring.rabbitmq.host=192.168.159.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
测试
访问config client
修改name为lisi,访问config server的 /actuator/bus-refresh 接口,刷新所有config client配置
再次请求config client,发现配置改变了
通配符方式
config server可以只通知部分客户端,添加destination参数,格式为服务 :端口。如/bus/refresh?destination=config-client:9000刷新config-client在9000的服务配置,config-client:**刷新config-client所有端口的服务配置
配置加密
如果是低版本jdk,因为JRE中自带的JCE功能,默认使用的是有长度限制的版本,我们要将其替换成不限长度的JCE版本
下载无长度限制的JCE版本
https://www.oracle.com/java/technologies/javase-jce8-downloads.html
解压得到两个jar包,将其复制到 %JAVA_HOME%\jre\lib\security
如果是高版本jdk,可以发现 %JAVA_HOME%\jre\lib\security\policy有两个 目录,limited和unlimited,jdk中已经自带了无限制长度的JCE
打开 java.security 文件,可以发现JCE默认使用无长度限制的策略文件
小试牛刀
新建个 config-server-encrypt 模块用来演示,配置加密算法的key,注意要在bootstrap.properties中配置
encrypt.key=abc123
查看加密接口是否正常
将字符串加密,注意同一个字符串每次加密后都生成了不同的加密字符串
解密字符串
Git保存加密配置
gitconfig/config-client-dev.properties
encrypt.name={cipher}1ed7524f123bf04b3f23ba2d0b82f3622af12600ab223e0941545e3214b9b291
通过config server就可以获取到加密字符串后会进行解密,然后把解密后的字符串给config client
安全配置
在config-server-encrypt添加spring-boot-starter-security依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
修改application.properties,添加账号密码
config-server-entrypt application.properties
spring.security.user.name=root
spring.security.user.password=root
再次访问 https://admin-pc:8081/config-client-dev.properties 就需要登录
输入上面配置的账号密码后就可以查看了
如果是config client需要连接config server,那么也需要在config client端配置账号密码
新建个 config-client-entrypt 模块做演示
config-client-entrypt bootstrap.properties
spring.cloud.config.username=root
spring.cloud.config.password=root
client端通过了安全认证拿到了配置
源码:https://codox.coding.net/public/springcloud-learning/springcloud-learning/git/files