版权声明:YETA https://blog.csdn.net/qq_28958301/article/details/88719048
出现背景
Spring Cloud Config用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端和客户端两个部分:
- 服务端:也称为分布式配置中心,是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口。
- 客户端:是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。
构建配置信息
- 依赖
- 启动类
- 配置
- Git仓库,为做版本控制建立两个分支
- 访问配置信息URL与配置文件的映射关系
- /{application}/{profile}[/{label}]
- 示例:http://localhost:9020/scl2/prod/config-label-test
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- 示例:http://localhost:9020/scl2-prod.properties
- /{label}/{application}-{profile}.properties
- 示例:http://localhost:9020/config-label-test/scl2-prod.properties
【备注】配置服务器在从Git中获取配置信息后,会存储一份在config-server的文件系统中,实质上config-server是通过git clone命令将配置内容复制了一份在本地存储,然后读取这些内容并返回给微服务应用进行加载。
客户端配置映射
- 依赖
- 配置
- 接口
- 测试
服务端详解
客户端应用从配置管理中获取配置信息遵从下面的执行流程:
- 应用启动时,根据bootstrap.properties中配置的应用名{application}、环境名{profile}、分支名{label},向Config Server请求获取配置信息;
- Config Server根据自己维护的Git仓库信息和客户端传递过来的配置定位信息去查找配置信息;
- 通过git clone命令将找到的配置信息下载到Config Server的文件系统中;
- Config Server创建Spring的ApplicationContext实例,并从Git本地仓库中加载配置文件,最后将这些配置内容读取出来返回给客户端应用;
- 客户端应用在获得外部配置文件后加载到客户端的ApplicationContext实例,该配置内容的优先级高于客户端Jar包内部的配置内容,所以在Jar包中重复的内容将不再被加载;
Git配置仓库
- 以本地仓库的方式运行
- 占位符配置URI、子目录存储
代码库以服务名作为Git仓库名称、配置库以服务名-config作为Gti仓库名称。
- 本地仓库
- 安全保护
- 配置中心引入依赖
-
- 配置中心配置
-
- 客户端配置
- 加密解密
- Oracle官网下载不限长度的JCE版本
https://www.oracle.com/technetwork/cn/java/javase/downloads/jce8-download-2133166-zhs.html
-
- 将文件复制到$JAVA_HOME/jre/lib/security目录下
-
- 配置中心注释依赖、注释安全校验配置,防止等会加密解密未授权
-
- 配置中心新建bootstrap.properties
-
- 启动配置中心,查看状态
-
- 加密
-
- 解密
-
- 设置Git仓库配置文件内容为加密后内容,并提交到Git仓库
-
- 还原刚才注释的依赖和配置
- 修改客户端接口,注入Git仓库中的配置文件的内容
-
- 调用接口,查看效果(可以看到,在Git仓库中的配置文件hello设置的加密后的world,但是这里显示的是解密后的,说明已经生效)
高可用配置
- 传统模式:将所有的Config Server都指向同一个Git仓库,这样所有的配置内容就通过统一的共享文件系统来维护,而客户端在指定给Config Server位置时,只需要配置Config Server上层的负载均衡设备地址即可。
- 服务模式:将Config Server作为一个普通的微服务应用,纳入Eureka的服务治理体系中。
客户端详解
- 服务化配置中心
- 配置中心和客户端引入依赖
-
- 配置中心和客户端启动类
-
- 配置中心配置
-
- 客户端配置
- 动态刷新配置
- 客户端引入依赖
-
- 修改配置,并动态刷新配置
POST http://localhost:9021/actuator/refresh
实例:API网关服务动态加载
API网关服务必须具备动态更新内部逻辑的能力,比如动态修改路由规则、动态添加/删除过滤器等。
- 动态路由:只需将API网关服务的配置文件通过Spring Cloud Config连接的Git仓库存储和管理
- 依赖
-
- 配置bootstrap.properties
-
- 启动类
-
- Git仓库配置
#传统路由配置
#单实例配置
#配置所有符合/api-a-url/**规则的访问都将被路由转发到http://localhost:8090/地址上
#如将http://localhost:5555/user-service/hello路由转发到http://localhost:8090/hello
#zuul.routes.user-service.path=/user-service/**
#zuul.routes.user-service.url=http://localhost:8090/
#多实例配置
#zuul.routes.user-service.path=/user-service/**
#zuul.routes.user-service.serviceId=user-service
#ribbon.eureka.enabled=false
#user-service.ribbon.listOfServers=http://localhost:8090/,http://localhost:8091/
#服务路由配置
#zuul.routes.user-service.path=/user-service/**
#zuul.routes.user-service.serviceId=user-service
#等于上两个配置
#zuul.routes.user-service=/user-service/**
#zuul.routes.user-consumer-feign.path=/user-consumer-feign/**
#zuul.routes.user-consumer-feign.serviceId=user-consumer-feign
#zuul.routes.user-consumer-feign=/user-consumer-feign/**
#对所有的服务都不自动创建路由规则
#zuul.ignored-services=*
#对/hello接口不自动创建路由规则
#zuul.ignored-patterns=/**/hello/**
#全局为路由规则增加前缀信息
#zuul.prefix=/api
#关闭移除代理前缀的动作
#zuul.strip-prefix=false
#对指定路由关闭溢出代理前缀的动作
#zuul.routes.user-service.strip-prefix=true
#本地跳转
zuul.routes.gateway.path=/gateway/**
zuul.routes.gateway.url=forward:/local
#配置传递敏感头信息
##通过设置全局参数为空来覆盖默认值
#zuul.sensitive-headers=
##通过指定路由的参数来配置
###方法一:对指定路由开启自定义敏感头
zuul.routes.user-consumer-feign.custom-sensitive-headers=true
###方法二:将指定路由的敏感头设置为空
#zuul.routes.user-consumer-feign.sensitive-headers=
#配置网关在进行路由转发前为请求设置Host头信息,以标识最初的服务端请求地址
zuul.add-host-header=true
#全局关闭重试机制
#zuul.retryable=false
#指定路由关闭重试机制
#zuul.routes.user-consumer-feign.retryable=false
#设置路由转发请求的时候,创建请求连接的超时时间
ribbon.ConnectTimeout=500
#设置路由转发请求的超时时间
ribbon.ReadTimeout=2000
#设置API网关中路由转发请求的HystrixCommand执行超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
#禁用指定的过滤器
#zuul.AccessFilter.pre.disable=true
-
- 修改测试
- 第一次获取所有路由
- 修改测试
-
-
- 修改Git仓库配置
-
-
-
- 动态刷新
-
-
-
- 第二次获取所有路由
-
- 动态过滤器:需要借助基于JVM实现的动态语言的帮助,比如Groovy
- 改造动态API网关服务
- 依赖
-
- Git仓库配置
#传统路由配置
#单实例配置
#配置所有符合/api-a-url/**规则的访问都将被路由转发到http://localhost:8090/地址上
#如将http://localhost:5555/user-service/hello路由转发到http://localhost:8090/hello
#zuul.routes.user-service.path=/user-service/**
#zuul.routes.user-service.url=http://localhost:8090/
#多实例配置
#zuul.routes.user-service.path=/user-service/**
#zuul.routes.user-service.serviceId=user-service
#ribbon.eureka.enabled=false
#user-service.ribbon.listOfServers=http://localhost:8090/,http://localhost:8091/
#服务路由配置
#zuul.routes.user-service.path=/user-service/**
#zuul.routes.user-service.serviceId=user-service
#等于上两个配置
zuul.routes.user-service=/user-service/**
#zuul.routes.user-consumer-feign.path=/user-consumer-feign/**
#zuul.routes.user-consumer-feign.serviceId=user-consumer-feign
zuul.routes.user-consumer-feign=/user-consumer-feign/**
#对所有的服务都不自动创建路由规则
zuul.ignored-services=*
#对/hello接口不自动创建路由规则
#zuul.ignored-patterns=/**/hello/**
#全局为路由规则增加前缀信息
#zuul.prefix=/api
#关闭移除代理前缀的动作
#zuul.strip-prefix=false
#对指定路由关闭溢出代理前缀的动作
#zuul.routes.user-service.strip-prefix=true
#本地跳转
zuul.routes.gateway.path=/gateway/**
zuul.routes.gateway.url=forward:/local
#配置传递敏感头信息
##通过设置全局参数为空来覆盖默认值
#zuul.sensitive-headers=
##通过指定路由的参数来配置
###方法一:对指定路由开启自定义敏感头
zuul.routes.user-consumer-feign.custom-sensitive-headers=true
###方法二:将指定路由的敏感头设置为空
#zuul.routes.user-consumer-feign.sensitive-headers=
#配置网关在进行路由转发前为请求设置Host头信息,以标识最初的服务端请求地址
zuul.add-host-header=true
#全局关闭重试机制
#zuul.retryable=false
#指定路由关闭重试机制
#zuul.routes.user-consumer-feign.retryable=false
#设置路由转发请求的时候,创建请求连接的超时时间
ribbon.ConnectTimeout=500
#设置路由转发请求的超时时间
ribbon.ReadTimeout=2000
#设置API网关中路由转发请求的HystrixCommand执行超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
#禁用指定的过滤器
#zuul.AccessFilter.pre.disable=true
#指定动态加载的过滤器存储路径
zuul.filter.root=filter
#配置动态加载的时间隔时间,单位秒
zuul.filter.interval=5
-
- 配置类
-
- 启动类
-
- 对应根目录下创建过滤器
【备注】添加过滤器,无需重启服务。但是删除Groovy文件并不能从当前运行改的服务中移除这个过滤器,可以设置shouldFilter为false实现。而且无法直接注入服务的Spring容器中加载的实例,比如无法注入RestTemplate等实例。