服务配置
目前在用的服务配置+服务总线的三套方案
Config+Bus
Naccos(Alibaba)
Apollo(携程)上海地区
一、SpringCloud Config 分布式配置中心
1. 概述
1.1 分布式系统面临的配置问题
微服务意味着要将单体应用中的业务拆分成一个个子服务, 每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
SpringCloud提供了ConfigServer来解决这个问题,我们每一个微服务自己带着一个application.yml,上百个配置文件的管理.... ./(ToT)/~~
目标
- 版本【生产环境prod、测试环境test、开发环境dev等】切换方便
- 一次配置,处处生效【比如切换数据库】
1.2 是什么
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
A、B、C的公共配置放到Config Server中,私有配置放在各自那
1.3 怎么玩
SpringCloud Config分为服务端和客户端两部分。
服务端也称为分布式配置中心,它是一个独立的微服务应用【Config Server也是一个微服务】,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
1.4 能干嘛
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta【预发布环境】/release【灰度发布】
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露,postman、curl访问刷新均可....
1.5 与Github整合配置
由于SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持svn和本地文件,但最推荐的还是Git,而且使用的是http/https访问的形式)
1.6 官网
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.1.RELEASE/reference/html/
2. Config服务端配置与测试
-
在Github上新建一个名为sprincloud-config的新Repository
-
本地拉取刚刚创建的sprincloud-config
执行
git clone git@github.com:wcnma/springcloud-config.git
如果出现如下错误
极大多数情况是由于github账号没有设置ssh公钥信息所致
在github账号中添加公钥信息即可
执行
cat ~/.ssh/id_rsa.pub
并将公钥添加到github账号中
重新拉取即可
-
建Module【cloud-config-center-3344】,它既为Cloud的配置中心模块CloudConfig Center
-
改POM
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud2020</artifactId> <groupId>com.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-center-3344</artifactId> <dependencies>
<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> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
-
写YML
server: port: 3344 spring: application: name: cloud-config-center cloud: config: server: git: # Github仓库URI uri: git@github.com:wcnma/springcloud-config.git # 搜索目录 search-paths: - springcloud-config # 读取分支 label: main eureka: client: service-url: defaultZone: http://localhost:7001/eureka
-
主启动【添加@EnableConfigServer注解】
package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; @SpringBootApplication @EnableConfigServer public class ConfigCenterMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigCenterMain3344.class, args); } }
-
测试
启动cloud-eureka-server7001
启动cloud-config-center-3344
如果启动过程中出现如下错误
将SSH链接换成HTTPS链接即可
如果启动过程中出现如下错误,重启几次即可
参考网站:https://blog.csdn.net/qq_41731201/article/details/123527717
访问http://localhost:3344/main/application-dev.yml,微服务可以从Github上获取配置内容
-
配置读取规则
{label}:分支名称
{application}:服务名,可以是yml中的spring.application.name
{profile}:环境
注:对于一个Github中固定的配置文件main分支下的application-dev.yml均可通过以下方式进行读取
-
/{label}/{application}-{profile}.yml
直接返回配置文件内容,如果读取了不存在的环境,返回{}
-
/{application}-{profile}.yml
不指定具体的分支,默认分支为master
-
/{application}/{profile}[/{label}]
分支为可选项,不指定具体的分支,默认分支为master,返回JSON串,如果读取了不存在的环境,返回如下内容
-
/{application}-{profile}.properties
-
/{label}/{application}-{profile}.properties
每一个配置文件,都支持上述多种读取方式
-
-
至此成功实现了用SpringCloud Config通过GitHub获取配置信息
3. Config客户端配置与测试
-
建Module【cloud-config-client-3355】
-
改POM
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud2020</artifactId> <groupId>com.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-client-3355</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
-
bootstrap.yml
客户端最终的配置=bootstrap.yml + application.yml
applicaiton.yml是用户级的资源配置项
bootstrap.yml是系统级的,优先级更加高【用于与服务端打交道,涉及配置文件的加载顺序和分级管理】 Spring Cloud会创建一个"Bootstrap Context" ,作为Spring应用的Application Context的父上下文。初始化的时候,"Bootstrap Context'负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的 Environment。
'Bootstrap' 属性有高优先级,默认情况下,它们不会被本地配置覆盖。'Bootstrap context和Application Context有着不同的约定,所以新增了一个bootstrap.yml文件,保证Bootstrap Context和Application Context配置的分离。
要将Client模块下的application.yml文件改为bootstrap:.yml,这是很关键的,
因为bootstrap.yml是比application.yml先加载的。bootstrap.ymI优先级高于application.ymlserver: port: 3355 spring: application: name: config-client cloud: # Config客户端配置 config: # 分支名称 label: main # 服务名 name: application # 环境 profile: dev # Config服务端地址 uri: http://localhost:3344 # 上述配置含义:加载http://localhost:3344/main/application-dev.yml配置内容到客户端本地 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka
-
主启动
package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3355.class, args); } }
-
业务类
package com.atguigu.springcloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){ return configInfo; } }
-
测试
启动cloud-eureka-server7001
启动cloud-config-center-3344
启动cloud-config-client-3355
访问http://localhost:3344/main/application-dev.yml,正常返回
访问http://localhost:3355/configInfo
成功实现了客户端从SpringCloud Config服务端获取到GitHub中的配置信息
-
分布式配置的动态刷新问题
修改GitHub上的配置文件内容
稍等一会儿后,ConfigServer配置中心3344同步进行更新
ConfigServer客户端3355则没有进行更新,必须重启才能读取最新的配置
4. Config客户端之动态刷新手动版
避免每次更新Github配置都要重启客户端微服务【比如3355】
-
修改cloud-config-client-3355的POM,引入actuator监控
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
修改cloud-config-client-3355的bootstrap.yml,添加如下内容
# 暴露监控端口 management: endpoints: web: exposure: include: "*"
-
修改cloud-config-client-3355的ConfigClientController,添加注解@RefreshScope
package com.atguigu.springcloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RefreshScope @RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){ return configInfo; } }
-
测试
启动EurekaMain7001
启动ConfigCenterMain3344
启动ConfigClientMain3355
修改Github中的配置
访问http://localhost:3344/main/application-dev.yml,配置已经更新了
cmd执行
curl -X POST "http://localhost:3355/actuator/refresh"
【必须是POST请求】访问http://localhost:3355/configInfo,配置更新,成功实现了客户端在不重启的情况下同步得到最新的配置
-
存在的问题
可否广播,一次通知,处处生效?
我们想大范围的自动刷新
配置更新后可以指定需要更新配置的微服务进行配置更新