【后面的话 】本文的某些常识依赖我的微服务系列文章,如果没有看过能够先移步去看一下。在后面的利用当中,咱们所有的配置都是写在yaml 配置文件当中的,这样就会造成几个问题:平安、对立治理等等。而 SpringCloud 也是思考到这一点,给出的计划就是Spring Cloud Config。
壹、Config 的简介
Spring Cloud Config 是 Spring Cloud 团队创立的一个全新我的项目,用来为分布式系统中的基础设施和微服务利用提供集中化的内部配置反对,它分为服务端与客户端两个局部。其中服务端也称为分布式配置核心,它是一个独立的微服务利用,用来连贯配置仓库并为客户端提供获取配置信息、加密 / 解密信息等拜访接口;而客户端则是微服务架构中的各个微服务利用或基础设施,它们通过指定的配置核心来治理利用资源与业务相干的配置内容,并在启动的时候从配置核心获取和加载配置信息。Spring Cloud Config 实现了对服务端和客户端中环境变量和属性配置的形象映射,所以它除了实用于 Spring 构建的应用程序之外,也能够在任何其余语言运行的应用程序中应用。因为 Spring Cloud Config 实现的配置核心默认采纳 Git 来存储配置信息,所以应用 Spring Cloud Config 构建的配置服务器,人造就反对对微服务利用配置信息的版本治理,并且能够通过 Git 客户端工具来不便的治理和拜访配置内容。当然它也提供了对其余存储形式的反对,比方:SVN 仓库、本地化文件系统。
贰、筹备工作
- 首先在工程上面新建 lovin-config-repo,作为寄存配置文件的中央,并且增加 dev,test,pro 的相干配置文件,最初在配置文件中增加token 的配置,具体见下图
- 新建一个 config 的服务端子工程lovin-config-server,用于前面的操作。上面是次要的 pom 依赖:
<parent>
<artifactId>lovincloud</artifactId>
<groupId>com.eelve.lovincloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lovin-config-server</artifactId>
<packaging>jar</packaging>
<name>lovinconfigserver</name>
<version>0.0.1</version>
<description> 配置服务端 </description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 这里为了平安,我这里还是增加spring-boot-starter-security
server:
port: 8886 # 服务端口号
spring:
application:
name: lovinconfigserver # 服务名称
security:
basic:
enabled: true
user:
name: lovin
password: ${REGISTRY_SERVER_PASSWORD:lovin}
cloud:
config:
server:
git:
uri: https://github.com/lovinstudio/lovincloud
search-paths: lovin-config-repo
label: master
eureka:
client:
serviceUrl:
defaultZone: http://lovin:lovin@localhost:8881/eureka/ # 注册到的 eureka 服务地址
- 下面的配置文件是用 git 作为配置文件管理中心,还有 svn 和本地文件系统两种,我这里也在上面简略列举以下:
git 版本配置
spring:
cloud:
config:
server:
git:
uri: https://github.com/lovinstudio/lovincloud
search-paths: lovin-config-repo
username: #如果是私人仓库,还须要配置用户名,公共仓库能够省略
password: #如果是私人仓库,还须要配置明码,公共仓库能够省略
label: master
svn 版本配置
spring:
cloud:
config:
server:
svn:
uri: http://192.168.0.6/svn/repo/config-repo
username: username
password: password
default-label: trunk
profiles:
active: subversion #这里须要显式申明为 subversion
同时还须要引入相应的配置:
<!--SVN-->
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit</artifactId>
</dependency>
本地版本配置
spring:
cloud:
config:
server:
native:
searchLocations: file:D:\\config #classpath:/config
profiles:
active: native #native
- 配置spring-boot-starter-security,这里为了不便我这里放开所有申请
package com.eelve.lovin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @ClassName WebSecurityConfig
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/18 13:52
* @Version 1.0
**/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().permitAll()
.and().csrf().disable();}
}
- 在主类上增加@EnableConfigServer,当然也须要注册到注册核心:
package com.eelve.lovin;
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;
/**
* @ClassName LovinEurekaClientApplication
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/15 16:37
* @Version 1.0
**/
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class LovinConfigServerApplication {public static void main(String[] args) {SpringApplication.run(LovinConfigServerApplication.class,args);
}
}
叁、启动测试
- 顺次启动 eureka 的服务端和新建的 lovin-config-server
- 拜访地址:http://chirius:8886/lovin-config/dev。
- 后果原始数据:
{"name":"lovin-config","profiles":["dev"],"label":null,"version":"f0aeca26887490e3bcb8be317d4dfb378313a76f","state":null,"propertySources":[{"name":"https://github.com/lovinstudio/lovincloud/lovin-config-repo/lovin-config-dev.properties","source":{"lovin.token":"lovin"}}]}
这时咱们通过浏览器、POSTMAN 或 CURL 等工具间接来拜访到咱们的配置内容了。拜访配置信息的 URL 与配置文件的映射关系如下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
下面的 url 会映射 {application}-{profile}.properties 对应的配置文件,其中{label} 对应 Git 上不同的分支,默认为 master。咱们能够尝试结构不同的 url 来拜访不同的配置内容,比方,要拜访 master 分支,config-client 利用的 dev 环境,就能够拜访这个 url:http://chirius:8806/lovin-config/dev,并取得如下返回:
这里有一点疑难,我通过 http://localhost:8886/lovin-config/dev/ 去拜访是始终不胜利的,然而在换成其余 github 下面他人的配置仓库又是能够间接拜访的
2019-08-19 12:55:54.686 INFO 9256 --- [nio-8886-exec-4] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/Chirius/AppData/Local/Temp/config-repo-8280352825025657146/lovin-config-repo/lovin-config-dev.properties
2019-08-19 12:55:57.560 INFO 9256 --- [nio-8886-exec-2] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname
2019-08-19 12:55:57.576 INFO 9256 --- [nio-8886-exec-2] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/Chirius/AppData/Local/Temp/config-repo-8280352825025657146/lovin-config-repo/lovin-config-dev.properties
2019-08-19 12:56:00.544 INFO 9256 --- [nio-8886-exec-1] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname
2019-08-19 12:56:00.559 INFO 9256 --- [nio-8886-exec-1] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/Chirius/AppData/Local/Temp/config-repo-8280352825025657146/lovin-config-repo/lovin-config-dev.properties
2019-08-19 12:56:07.136 INFO 9256 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
2019-08-19 13:01:07.140 INFO 9256 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
2019-08-19 13:06:07.142 INFO 9256 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
ps:通过日志咱们能够看到配置文件是被保留在咱们本地的,当然咱们也就能够通过配置,批改保留的门路,具体配置为:basedir
肆、新建配置客户端
新建一个 config 的服务端子工程lovin-config-client,用于前面的操作。上面是次要的 pom 依赖:
<parent>
<artifactId>lovincloud</artifactId>
<groupId>com.eelve.lovincloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lovin-config-client</artifactId>
<packaging>jar</packaging>
<name>lovinconfigclient</name>
<version>0.0.1</version>
<description> 配置生产端 </description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
ps:在这里为了监控配置变动咱们须要增加 spring-boot-starter-actuator 的依赖
- 这里为了平安,我这里还是增加 spring-boot-starter-security 的配置
- 新建bootstrap.yml
spring:
cloud:
config:
name: lovin-config
profile: dev
uri: http://localhost:8886/
label: master
eureka:
client:
serviceUrl:
defaultZone: http://lovin:lovin@localhost:8881/eureka/ # 留神在高可用的时候须要见注册核心配置移到该文件中,在 application.yml 中见会读取不到配置
- 增加application.yml
server:
port: 8807 # 服务端口号
spring:
application:
name: lovinconfigclient # 服务名称
security:
basic:
enabled: true
user:
name: lovin
password: ${REGISTRY_SERVER_PASSWORD:lovin}
- 配置spring-boot-starter-security,这里为了不便我这里放开所有申请
package com.eelve.lovin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @ClassName WebSecurityConfig
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/20 16:59
* @Version 1.0
**/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().permitAll()
.and().csrf().disable();}
}
- 咱们须要注册到注册核心:
package com.eelve.lovin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @ClassName LovinEurekaClientApplication
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/15 16:37
* @Version 1.0
**/
@SpringBootApplication
@EnableEurekaClient
public class LovinConfigClientApplication {public static void main(String[] args) {SpringApplication.run(LovinConfigClientApplication.class,args);
}
}
- 增加 ConfigController 用来测试获取配置
package com.eelve.lovin.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName ConfigController
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/20 17:17
* @Version 1.0
**/
@RestController
@RefreshScope // 应用该注解的类,会在接到 SpringCloud 配置核心配置刷新的时候,主动将新的配置更新到该类对应的字段中。public class ConfigController {@Value("${lovin.token}")
private String token;
@RequestMapping("/token")
public String getToken() {return this.token;}
}
PS:其中 RefreshScope 注解是为了刷新配置来增加的,这样让配置仓库中的配置产生扭转的时候,咱们能够通过拜访 /refresh 申请来刷新配置(由 spring-boot-starter-actuator 提供的监控性能)
通过客户端去拜访获取配置数据
- 拜访http://localhost:8807/token,见下图
- 批改配置,而后再次拜访,咱们能够看到配置是没有变更的
- 刷新配置再次拜访
能够看到这是咱们曾经获取到了最新的配置,过后这样就存在一个问题,每一个配置客户端都须要刷新配置,会十分麻烦,也很容易出错。解决方案由 webhook 来刷新配置,然而这个不是最好的解决办法。然而咱们能够通过音讯总线来解决,这里见会在下一篇文章中具体解说,在这里就不作赘述了。
- 最初的最初是本博客的源码, 欢送关注这一套 SpringCloud 的实际