分布式配置中心能做什么
- 比如使用同一个redis的不同微服务,都需要单独进行redis配置,这是很麻烦的,因此可以通过分布式配置中心抽取公共配置
- 修改配置文件,需要重启系统,因此需要实现配置文件的热加载
分布式配置中心搭建
jar包导入
-
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
启动类
-
package com.xiangxue.jack; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /* post * 加密:http://localhost:8085/encrypt?data=123456 * 解密:http://localhost:8085/decrypt * */ @SpringBootApplication(scanBasePackages = { "com.xiangxue.jack"}) @EnableConfigServer // 注册到eureka @EnableEurekaClient public class MicroConfigServerApplication { public static void main(String[] args) { SpringApplication.run(MicroConfigServerApplication.class,args); } }
- @EnableConfigServer的注解
分布式配置中心的配置规则
配置文件
-
此处是用的github,也可以用git、gitlab、svn等等
-
spring.cloud.config.server.git.uri=https://github.com/zg-jack/zg-config-repo spring.cloud.config.server.git.search-paths=config-repo spring.cloud.config.server.git.username=zg-jack spring.cloud.config.server.git.password=zg0001jack
客户端使用分布式配置中心
jar包导入
-
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>LATEST</version> </dependency>
配置文件
-
#环境 spring.cloud.config.profile=dev #分支 spring.cloud.config.label=master #这种配置是configserver还单机情况,直接连接这个单机服务就行 spring.cloud.config.uri=http://localhost:8085/
实例使用
-
package com.xiangxue.jack.controller; import com.xiangxue.jack.bean.ConsultContent; import com.xiangxue.jack.service.UserService; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.List; @RefreshScope @RestController @RequestMapping("/user") public class UserController { private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()); @Autowired UserService userService; @Value("${username}") private String username; @Value("${redis.password}") private String redispass; @Value("${db.password}") private String dbpass; @Autowired Environment environment; @RequestMapping("/queryContent") public List<ConsultContent> queryContent(HttpServletRequest request) { logger.info(""+this.hashCode()); logger.info("==================已经调用==========" + request.getRemotePort()); logger.info("@Value======username======" + username); logger.info("Environment======username======" + environment.getProperty("username")); logger.info("@Value======redispass======" + redispass); logger.info("Environment======redispass======" + environment.getProperty("redis.password")); logger.info("zookeeper======zk.jack.url======" + environment.getProperty("configzk.jack.url8")); return userService.queryContent(); } }
- 方法1:@Value("${username}")
- 依赖注入时实际就是通过方法2获取的
- 方法2:environment.getProperty(“username”)
- 方法1:@Value("${username}")
-
github的master分支下有一个文件micro-order-dev.properties
-
username=zg-jack-dev---20200224-9-bus password=123456cc spring.datasource.url=jdbc:mysql://127.0.0.1:3306/consult?serverTimezone=UTC redis.password={cipher}一个加密串
-
客户端快速失败和重试
-
当你启动客户端时,发现连不上,此时就不需要启动服务了,可以快速失败
-
#如果连接不上获取配置有问题,快速响应失败 spring.cloud.config.fail-fast=true
-
-
启动过程的重试
-
#默认重试的间隔时间,默认1000ms spring.cloud.config.retry.multiplier=1000 #下一间隔时间的乘数,默认是1.1 #spring.cloud.config.retry.initial-interval=1.1 #最大间隔时间,最大2000ms spring.cloud.config.retry.max-interval=2000 #最大重试次数,默认6次 spring.cloud.config.retry.max-attempts=6
-
同时需要导入jar包
-
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
-
-
配置信息的加密
-
比如对一些敏感信息,像账号密码
-
加密:http://localhost:8085/encrypt?data=123456 解密:http://localhost:8085/decrypt
-
需要加入密钥配置,非对称加密是通过RSA算法实现,有公钥和私钥,根据私钥加密,根据公钥解密,加密和解密都有密钥,是成对存在的
-
在/jdk/jre/bin/keytool.exe中执行如下指令,会在该目录下生成密钥文件config-server.keystore,输入指令的过程中会需要输入密码,之后需要配置到配置文件中,encrypt.key-store.password和encrypt.key-store.secret
-
keytool -genkeypair -alias config-server -keyalg RSA -keystore config-server.keystore -validity 365
-
-
配置项
-
#加密配置 #生成的密钥文件 encrypt.key-store.location=config-server.keystore #与keytool指令对应 encrypt.key-store.alias=config-server encrypt.key-store.password=123456 encrypt.key-store.secret=123456
-
-
把密钥文件放在resource下面,同时修改pom文件,把**/*.keystore加进去
-
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.txt</include> <include>**/*.keystore</include> </includes> <filtering>false</filtering> </resource> </resources>
-
-
-
config server的缓存
-
#本地缓存目录 spring.cloud.config.server.git.basedir=C:/work/config/tmp #强制从GitHub配置中心中拉取配置信息,不走缓存 spring.cloud.config.server.git.force-pull=true
-
强制不走缓存,防止更新无效
服务化配置中心
-
如何在客户端设置配置中心?
-
1.直接指定机器
-
#这种配置是configserver还单机情况,直接连接这个单机服务就行 spring.cloud.config.uri=http://localhost:8085/
-
-
2.配置中心启动成功,通过配置中心名称连接
-
#开启configserver服务发现功能 spring.cloud.config.discovery.enabled=true #服务发现的服务名称 spring.cloud.config.discovery.service-id=config-server
-
-
高可用
- 将配置中心项目打成jar包,在不同机器上分别启动1个配置中心
配置动态刷新
-
@Value("${username}") private String username; @Value("${redis.password}") private String redispass; @Value("${db.password}") private String dbpass; @Autowired Environment environment;
-
这些属性在启动时已经依赖注入了,如何使值动态改变?
- 需要调用接口:http://localhost:8086/actuator/refresh,调用接口之后,再去请求,发现@value的方式还是旧值,environment的方式是新值了
- 没有加注解@RefreshScope前,调用刷新接口后@Value值并没有更新,加了注解@RefreshScope后,调用刷新接口@Value的值也实现了动态刷新
-
Environment,只要调用刷新接口就能成功动态刷新新的参数
-
缺点
-
1.必须手动调用,才能刷新接口
- 可以借助github的通知功能,配置一个回调地址
-
2.对多机情况,调用刷新接口,只对单机生效,要调n次才能刷新完
- 消息总线可以解决
消息总线
导入jar包
-
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
mq的配置信息
-
spring.rabbitmq.host=192.168.67.139 spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=admin
刷新总线配置
-
# 刷新配置url http://localhost:8085/actuator/bus-refresh spring.cloud.bus.refresh.enabled=true spring.cloud.bus.trace.enabled=true
测试
- 调用总线刷新接口后,所有分布式配置中心的客户端都会自动刷新,这是广播-发布与订阅实现的,调用总线刷新接口后,就会往mq队列插一条消息,并且广播给所有的客户端,客户端会消费这条消息,并刷新最新配置
- 192.168.67.139:15672/#/queues,rabbitmq的控制台