配置中心再微服务中的应用
常规的配置定义
- 程序 Hardcode 写死再代码中
- 配置文件,万年不变的配置 application.yml| bootstrap.yml
- 环境变量 操作系统层面和设置启动参数
- 数据存储 压力大,数据库可能承受不了
配置管理缺点
- 格式不统一---json,properties,yml
- 没有版本控制---放飞自我想改就改
- 基于静态配置---修改,发布流程繁琐(直接写在代码中的配置)
- 分布零散---没用统一管理
配置项的静态内容
- 环境配置
- 数据库连接串
- Eureka注册中心
- Kafka连接
- 应用名称
- 安全配置(加密)
- 连接密码
- 公钥私钥
- HTTP连接Cert
配置项的动态内容
- 功能控制
- 功能开关
- 人工熔断
- 蓝绿发布
- 数据源切换
- 业务规则
- 当日外汇利率
- 动态文案
- 规则引擎参数
- 应用参数
- 网管黑白名单
- 缓存过期时间
- 日志MDC设置
配置管理的需求
- 高可用
- 版本管理
- 修改记录
- 版本控制,权限控制
- 业务需求
- 内容加密
- 动态推动变更
- 配置分离,中心化管理
准备
创建GitHub配置仓库
1 创建GitHub仓库
- 创建config-repo名的公共仓库
2 文件命名规则(文件名不能随便起)
- Application(应用名称) & Profile(项目环境) {application}-{profile}.yml
{application}-{profile}.properties
- Labe - 代码分支的名称
3 添加配置文件和属性
# comfig-consumer-dev.yml
info:
profile: dev
name: Saul
word: 'God bless me'
# comfig-consumer-prod.yml
info:
profile: prod
name: Paul
word: 'God bless you'
搭建配置中心
创建config-server项目引入依赖
# pom.xml
<artifactId>config-server</artifactId>
<name>config-server</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
添加参数和启动类
- 启动类
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ConfigServerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
- application.yml配置文件
server:
port: 60000
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/afterglow-now/config-repo.git
# 子目录,可以支持多个文件或者通配符
search-paths: abc,def,def*
# 解决could not be established because of SSL problems错误
skipSslValidation: true
# 用户名
username:
# 密码
password:
# 强制拉去资源文件
force-pull: true
通过GET请求拉去文件(URL的几种Pattern)
- 第一种
- http://localhost:60000/{application}/{profile}/{label}
- http://localhost:60000/config-consumer/prod
- 可以再最后加上label,默认为master
- http://localhost:60000/config-consumer/prod/master
- 第二种
- http://localhost:60000/{label}/{application}-{profile}.yml (.json,.properties)
- http://localhost:60000/config-consumer-prod.yml
- http://localhost:60000/config-consumer-prod.properties
- http://localhost:60000/config-consumer-prod.json
- 如果需要添加label则直接再端口后接label
- http://localhost:60000/master/config-consumer-prod.yml
Client直连配置中心
创建config-client项目引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--在SpringCloud 2020.* 版本把bootstrap禁用了,导致在读取文件的时候读取不到而报错-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
配置启动项和启动类
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ConfigClientApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
注入GitHub属性到测试用例
- bootstrap.yml
server:
port: 61000
spring:
application:
name: config-client
cloud:
config:
uri: http://localhost:60000
profile: dev
label: main
name: config-consumer
- controller类
@RestController
public class Controller {
@Value("${name}")
private String name;
@Value("${myWord}")
private String word;
@GetMapping("/name")
public String getName(){
return name;
}
@GetMapping("/word")
public String getWord(){
return word;
}
}
动态拉去参数
引入特殊依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
改造config-client
- 新增controller
@RestController
@RequestMapping("/refresh")
// 动态刷新配置信息
@RefreshScope
public class RefreshController {
@Value("${word}")
private String word;
@GetMapping("/word")
public String getWord(){
return word;
}
}
- 新增配置内容bootstrap.yml
management:
security:
enabled: false
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
- 通过actuator暴露继续刷新修改后的内容 post 类型接口:http://localhost:61000/actuator/refresh
配置中心高可用
- Config的高可用方式:Eureka注册中心进行集群处理
- 其他高可用方式:服务发起请求,网管进行负载均衡
Eureka高可用
config-server项注册中心报道
- 创建 config-server-eureka项目
- 新增依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 新增配置文件
server:
port: 60001
spring:
application:
name: config-server-eureka
cloud:
config:
server:
git:
uri: https://github.com/afterglow-now/config-repo.git
# 强制拉去资源文件
force-pull: true
# 解决could not be established because of SSL problems错误
skipSslValidation: true
eureka:
instance:
preferIpAddress: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://localhost:20000/eureka/
- 创建主类
@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerEurekaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ConfigServerEurekaApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
config-client从注册中心获取config-server地址
- 在config-client中新增eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 在启动类上加
@EnableDiscoveryClient注解 - 修改application.yml文件
server:
port: 61000
spring:
application:
name: config-client
cloud:
config:
# uri: http://localhost:60000
discovery:
enabled: true
service-id: config-server-eureka
profile: dev
label: main
name: config-consumer
eureka:
instance:
preferIpAddress: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://localhost:20000/eureka/
management:
security:
enabled: false
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
配置属性使用密钥对称加密
在JDK中替换JCE
- 不限长度的JCE组件组件下载(注意下载对应JDK版本的组件)
- www.oracle.com/technetwork…
改造config-server并生成加密字符串
- 添加bootstrap.yml文件
encrypt:
# 加密的key
key: clay
- 使用get类型请求访问验证状态: http://localhost:60001/encrypt/status
修改GitHub文件,启动服务拉去配置
- 加密和解密在config-server
- 加密: post请求发起text/plain数据类型到http://localhost:60001/encrypt
- 解密: post请求发起text/plain数据类型到http://localhost:60001/decrypt
GitHub修改
# {cipher}通知config-server需要解密
food: '{cipher}6dfc2702b50b1f77195ab4316617a0e87e6b54c1aae4d6f27e155205bce1aca4'