SpringCloudConfig 分布式配置
1. 分布式系统面临的配置文件的问题
微服务意味着要将单体应用中的业务拆分成一个个子服务, 每个服务的粒度相对较小,因此系统中会出现大量的服务,由于每个服务都需要必要的配置信息才能运行,所以一套集中式的, 动态的配置管理设施是必不可少的。
SpringCloud提供了ConfigServer来解决这个问题,我们每一个微服务自己带着一个application.yml,那上百的的配置文件要修改起来,岂不是要发疯!
Spring Cloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环节提供了一个中心化的外部配置。
Spring Cloud Config 分为服务端和客户端两部分;
服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密,解密信息等访问接口。
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理。并且可以通过git客户端工具来方便的管理和访问配置内容。
[
](https://www.springcloud.cc/spring-cloud-greenwich.html#_spring_cloud_config)
SpringCloud Config官网说明
2. SpringCloud Config分布式配置中心能做什么
集中管理配置文件
不同环境,不同配置,动态化的配置更新,分环境部署,比如/dev /test/ /prod /beta /release
运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息。
当配置发生变动时,服务不需要重启,即可感知到配置的变化,并应用新的配置
将配置信息以REST接口的形式暴露
SpringCloud config分布式配置中心与github整合
由于Spring Cloud Config默认使用Git来存储配置文件(也有其他方式,比如支持SVN和本地文件), 但是最推荐的还是Git,而且使用的是http / https访问的形式;
Config配置服务端环境
1:在个人git中创建相关链接,使用远程git进行对服务控制
2:创建springcloud-config 控制中心服务
3:导入相关依赖,修改pom文件
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.junjay</groupId>
<artifactId>SpringCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.junjay</groupId>
<artifactId>springcloud-config-server-3344</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-config-server-3344</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 消费者只需要实体类+web -->
<dependency>
<groupId>com.junjay</groupId>
<artifactId>springcloud-pai</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 添加负载均衡Ribbon依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 加入eureka依赖进行服务注册 -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 加入config控制中心 -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-config-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
</project>
3:添加yml配置
server:
port: 3344
#spring配置
spring:
application:
name: springcloud-config-server
# 链接远程仓库 cloud-config cloud配置
cloud:
config:
# server 服务
server:
# 服务选择:svn,git
git:
# 是uri不是url,地址是https,不是ssh
uri: https://github.com/My-Jun/SpringCloud-Netflix-Kss-Config.git
4:编写启动类,开启enable*注解
package org.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer // 开启config服务
public class Config_Server_3344 {
public static void main(String[] args) {
SpringApplication.run(Config_Server_3344.class, args);
}
}
5:启动服务正常
6:访问启动服务地址+git中文件
http://localhost:3344/application-dev.yml
springcloud使用git作为config配置中心(解决错误404或者是No such label: master问题)
问题:默认的label为master
Github现在master改为main, 修改 default-label 属性, 否则读不到,修改yml
server:
port: 3344
#spring配置
spring:
application:
name: springcloud-config-server
# 链接远程仓库 cloud-config cloud配置
cloud:
config:
# server 服务
server:
# 服务选择:svn,git
git:
# 是uri不是url,地址是https,不是ssh
uri: https://github.com/My-Jun/SpringCloud-Netflix-Kss-Config.git
# 默认的label为master
# Github现在master改为main, 修改 default-label 属性, 否则读不到
default-label: main
服务的本质并没有做什么,而是通过config-server,可以链接到我们的github上,去访问其中的资源以及配置。
6:HTTP多种方式访问git地址内容
HTTP服务具有以下形式的资源:
application:应用程序,
profile-模式:(dev,test)
label:具体分支
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
eg:http://localhost:3344/application/test/
如果访问yml中没有的内容则
[
](https://www.springcloud.cc/spring-cloud-config.html)
Config配置客户端环境
1:创建config-client.yml配置文件
2:创建客服端链接GIT
3:pom添加相关依赖jar
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.junjay</groupId>
<artifactId>SpringCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.junjay</groupId>
<artifactId>springcloud-config-client-3355</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-config-client-3355</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 添加config启动jar -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
3:添加配置文件yml
# 用户级别配置
#spring配置
spring:
application:
name: springcloud-config-client
# 根配置文件,系统级别配置
spring:
cloud:
config:
# 远程想要读取的文件
name: config-client
# 拿去服务配置环境dev,test
profile: dev
# 拿去哪个分支的代码
label: main
uri: http://localhost:3344
4:编写客服端Controller层
package org.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController {
/**
* 项目名字
*/
@Value("${spring.application.name}")
private String application;
/**
* eureka服务
*/
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaServer;
/**
* port服务端口
*/
@Value("${server.port}")
private String port;
/**
* 获取远程配置内容
*
* @return
*/
@RequestMapping("/config")
public String getConfig() {
String s = "application=%s;eurekaServer=%s;port=%s;";
return String.format(s, application, eurekaServer, port);
}
}
5:编写主启动类
package org.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
public class Config_Server_3355 {
public static void main(String[] args) {
SpringApplication.run(Config_Server_3355.class, args);
}
}
6:启动config服务端
启动服务端正常可以 访问在git中添加的新配置文件,config-client文件
7:启动客服端访问
服务端口已变成远程配置文件中端口
7:进行访问远程git仓库中的信息
8:修改bootstrap配置文件选择profile其他环境
profile: test
启动服务重现查看
服务端口已切换为git环境中的test 的port
http://localhost:8202/config
Config远程配置全yml
Config-eureka-7001远程服务
1:使用远程链接配置文件,配置eureka集群
2:导入与本地eureka服务相同jar,并添加springcloud-config包
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.junjay</groupId>
<artifactId>SpringCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.junjay</groupId>
<artifactId>springcloud-config-eureka-7001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-config-eureka-7001</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 导包eureka -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加config启动jar -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
</project>
3:服务原来eureka服务代码至新的config-eureka中
3:配置yml文件bootstrap.yml、application.yml
bootstrap.yml
# 根配置文件,系统级别配置
spring:
cloud:
config:
# 远程想要读取的文件
name: config-eureka
# 拿去服务配置环境dev,test
profile: test
# 拿去哪个分支的代码
label: main
uri: http://localhost:3344
application.yml
spring:
application:
name: springcloud-eureka-7001
4:启动config-eureka服务进行远程访问
5:首先访问3344开是否可以访问到config-eureka文件
http://localhost:3344/config-eureka-dev.yml
6:访问eureka中心,通过远程配置文件地址访问
Config-provider-dept-8001远程服务
1:新建Config-provider-dept-8001 远程服务
2:导入与springcloud-provider-dept-8081项目一样的jar和config-jar
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.junjay</groupId>
<artifactId>SpringCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.junjay</groupId>
<artifactId>springcloud-config-provider-dept-8081</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-config-provider-dept-8081</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 我们需要拿到实体类,所以需要配置api-module -->
<dependency>
<groupId>com.junjay</groupId>
<artifactId>springcloud-pai</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 引用父工程中定义好的jar直接引用无需选择版本,因为在父工程中已经设置 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- jetty 内置是tomcat 也可以使用jetty -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- Failed to configure a DataSource: 'url' attribute is not specified
and -->
<!-- no embedded 的三种解决办法 -->
<!-- 导致这个问题的原因是因为,在 pom.xml 配置文件中,配置了数据连接技术 spring-boot-starter-jdbc 包
,在启动配置文件时 ,Spring Boot 的自动装配机制就会去配置文件中找,相关的数据库的连接配置信息,如果找不到则抛出异常信息(具体源码就不在这儿分析了,有兴趣的可以自行去查看 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 加入eureka依赖进行服务注册 -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- actuator 完善监控信息 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 加入config控制中心 -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-config-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
</project>
3:配置yml文件以及复制原8001代码
application.yml
# 用户级别配置
#spring配置
spring:
application:
name: springcloud-config-eureka-7001
bootstrap.yml
# 根配置文件,系统级别配置
spring:
cloud:
config:
# 远程想要读取的文件
name: config-eureka
# 拿去服务配置环境dev,test
profile: test
# 拿去哪个分支的代码
label: main
uri: http://localhost:3344
4:启动服务进行访问测试
先测试3344 是否能拿到config-dept文件
5:通过config-dept 访问服务
http://localhost:8081/dept/queryById/1,因为本地配置的是dev环境所以数据库是db01
修改bootstrap.yml中的profile: dev 改为test 测试是否 成功访问数据库db02
# 根配置文件,系统级别配置
spring:
cloud:
config:
# 远程想要读取的文件
name: config-dept
# 拿去服务配置环境dev,test
profile: test
# 拿去哪个分支的代码
label: main
uri: http://localhost:3344
重启访问即可