springcloud-config配置中心的搭建与使用

前言:

公司的所有cloud微服务项目,目前都是在配置文件中配置了多套环境的配置文件,然后在启动时指定配置文件来加载启动。这样虽说可以,但是十分不便捷。在项目启动后,不能动态的修改配置参数,如果修改配置信息,只能通过重启服务器来实现。

之前对接的一个其他团队做的项目中,他们用到了apollo配置中心来统一管理配置文件,那么springcloud中有没有提供类似的配置中心服务呢?

答案是 当然是有的——springcloud-config!

springcloud-config介绍:

Spring Cloud Config为服务端和客户端提供了分布式系统的外部化配置支持。配置服务器为各应用的所有环境提供了一个中心化的外部配置。它实现了对服务端和客户端对Spring Environment和PropertySource抽象的映射,所以它除了适用于Spring构建的应用程序,也可以在任何其他语言运行的应用程序中使用。作为一个应用可以通过部署管道来进行测试或者投入生产,我们可以分别为这些环境创建配置,并且在需要迁移环境的时候获取对应环境的配置来运行。
言简意赅的来说:

Spring Cloud Config 是一种用来动态获取Git、SVN、本地的配置文件的一种工具

本文就以git为例,进行动态获取git上配置信息

如果需要svn如何配置的,可以参考文章底部的参考文档链接

(一)搭建config-client

1.利用idea快速构建一个springboot项目conf-server,可以加上基础的springboot所需依赖

2.引入springcloud-confg的pom依赖,我的pom如下:

        
		org.springframework.boot
		spring-boot-starter-parent
		2.0.0.RELEASE
		 
	
	com.configserver
	configserver
	0.0.1-SNAPSHOT
	configserver
	Demo project for Spring Boot

	
		1.8
		Finchley.RELEASE
	

	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.cloud
			spring-cloud-config-server
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	

	
		
			
				org.springframework.cloud
				spring-cloud-dependencies
				${spring-cloud.version}
				pom
				import
			
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

需要注意的是:之前我们一般都是用的各种starter,而这个config server不是spring-cloud-starter-config-server而是spring-cloud-config-server

3.启动类加上@EnableConfigServer

@EnableConfigServer
@SpringBootApplication
public class ConfigserverApplication {
	public static void main(String[] args) {
		SpringApplication.run(ConfigserverApplication.class, args);
	}
}

4. application.properties中进行配置

server.port=7001
spring.application.name=config-server

# git管理配置
#配置git仓库位置
spring.cloud.config.server.git.uri=http://config-server.git/
#配置仓库路径下的相对搜索位置,可以配置多个,多个之间用逗号分隔
spring.cloud.config.server.git.searchPaths=versions
#访问git仓库的用户名
spring.cloud.config.server.git.username=username
#访问git仓库的用户密码
spring.cloud.config.server.git.password=password

注意!注意!注意!

git.uri的路径最后后一定要加   /   。
不能把路径最后的 / 省略,想着放在git.searchPaths的参数的最前面。如果你这样做,那么后面测试时,地址会404。
我是测试时是这样的,如果你的没问题的话,欢迎交流~

 

Spring Cloud Config也提供本地存储配置的方式。我们只需要设置属性spring.profiles.active=native,Config Server会默认从应用的src/main/resource目录下检索配置文件。也可以通过
spring.cloud.config.server.native.searchLocations=file:F:/properties/属性来指定配置文件的位置。虽然Spring Cloud Config提供了这样的功能,但是为了支持更好的管理内容和版本控制的功能,还是推荐使用git的方式。
 

到这里,我们已经搭建完毕一个springcloud-config项目,并使用git管理内容的配置中心已经完成了,启动该应用,成功后开始下面的内容。

(二) 配置git信息

1.我们在git中配置一些不同环境的配置文件,用以测试是否可以获取到相应配置信息

我们在git的versions目录下,创建三个配置文件

  • didispace-dev.properties
  • didispace-local.properties
  • didispace-test.properties

2. 在每个配置文件中,加入一条相同的配置信息(最后会在客户端查询配置文件中的这条配置信息,以验证是否是当前配置文件)

  • from=git-dev-1.0
  • from=git-local-1.0
  • from=git-test-1.0

3.当前是master分支,我们在实际开发中,肯定会有不同环境下的分支,所以我们再可以建一条test分支,一会儿来测试不同分支下,拉取配置信息。

test分支内的from信息,就定义为2.0吧,用来和master内的from进行区分

我的git如下图所示:

springcloud-config配置中心的搭建与使用_第1张图片

springcloud-config配置中心的搭建与使用_第2张图片

springcloud-config配置中心的搭建与使用_第3张图片

springcloud-config配置中心的搭建与使用_第4张图片

到这一步,我们的config-server项目和相应的git环境就配置好了!下面我来调试一下,看搭建的是否正确

(三) 测试:

用postman等工具,来通过config-server服务来访问我们在git上的配置信息。

那么我们的路径是什么?应该咋写呢?

1.首先ip+端口号,自然就是我们config-server服务的ip与端口号了

2.后面的url与git配置文件的映射规则如下:

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

这就应该有同学迷茫了,这里的这几个分别代表什么意思?其实我刚开始也挺迷茫,

这里其实对应的我们刚刚git上配的文件与分支的一些名字
以上面git为例:

  • application:didispace (即配置文件名   -  前部分)  应用名
  • profile:dev  (即配置文件名   -  后部分)  环境名
  • label:master (分支名)   分支名

比如:http://127.0.0.1:7001/didispace/dev/test   注:用get方式请求

上面的url会映射{application}-{profile}.properties对应的配置文件

注意:

  1. 第一个规则的分支名是可以省略的,默认是master分支
  2. 无论你的配置文件是properties,还是yml,只要是应用名+环境名能匹配到这个配置文件,那么就能取到
  3. 如果是想直接定位到没有写环境名的默认配置,那么就可以使用default去匹配没有环境名的配置文件
  4. 使用第一个规则会匹配到默认配置
  5. 如果直接使用应用名来匹配,会出现404错误,此时可以加上分支名匹配到默认配置文件
  6. 如果配置文件的命名很由多个-分隔,此时直接使用这个文件名去匹配的话,会出现直接将内容以源配置文件内容直接返回,内容前可能会有默认配置文件的内容

最后,我们通过postman调用一下,会返回相应的结果:
springcloud-config配置中心的搭建与使用_第5张图片

此时我们查看控制台打印,会发现它的工作原理

是使用git clone 方式,将配置文件拉取到本地,将配置文件的信息传输给接收端

 

好了,到这里,我们springcloud-server与git相关的配置已经搭建并测试OK了!

但我们要如何使用?那就需要一个客户端(即我们平时springcloud的各个服务)了,用客户端通过config-server服务去git动态拉去上面的配置信息,以达到我们本文刚开始的目的!

(四) 搭建客户端(即一个微服务应用程序)

1.首选也是用idea快速构建一个springboot项目

2.pom引入所需的spring-cloud-starter-config依赖

    4.0.0
	
		org.springframework.boot
		spring-boot-starter-parent
		2.0.0.RELEASE
		 
	
	com.getconfiginfo
	get-configinfo
	0.0.1-SNAPSHOT
	get-configinfo
	Demo project for Spring Boot

	
		1.8
		Finchley.RELEASE
	

	
		
			org.springframework.boot
			spring-boot-starter-web
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		

		
			org.springframework.cloud
			spring-cloud-starter-config
		
		
		
			org.springframework.boot
			spring-boot-starter-actuator
		
	

	
		
			
				org.springframework.cloud
				spring-cloud-dependencies
				${spring-cloud.version}
				pom
				import
			
		
	
	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

3.启动类没有必须要加入的,按照你当前项目所需的启动类配置就好

4.创建bootstrap.properties配置文件!bootstrap.properties!!bootstrap!!!

spring.application.name=didispace
#已在git配置端口
#server.port=7002

#对应git配置文件中的{application}部分
spring.cloud.config.name=didispace
#对应git配置文件中的{profile}部分
spring.cloud.config.profile=dev
#对应git配置文件的git分支
spring.cloud.config.label=master
#config-server配置中心的地址
spring.cloud.config.uri=http://localhost:7001/


#开启和暴露refresh端点,也可以  *  暴露所有端点
#在1.5.* 以上默认开通了安全认证,如果不关闭会要求权限 management.security.enabled=false
#management.security.enabled=false
#在2.*版本后,management.security.enabled=false失效,新配置为:
#注意在使用Http访问端点时,需要加上默认/actuator 前缀
management.endpoints.web.exposure.include=refresh

重要的事情说三遍,所以:

上面这些属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。

5. 创建一个Rest API(即controller)

/**
 * @RefreshScope:当有请求/fresh节点的时候,会重新请求一次ConfigServer去拉取最新的配置文件
 * 请求/fresh需要有几点要求:1.加actuator的依赖 2.SpringCloud1.5以上需要设置 management.security.enabled=false
 * 这个Controller的作用是查看from这个key的值
 */
@RefreshScope//开启更新功能
@RestController
public class TestController {

    @Value("${from}")
    private String from;

    @RequestMapping("/from")
    public String from() {
        return this.from;
    }
}

通过@Value("${from}"),我们可以获取到在git配置文件中配置的form参数的值,

我们启动该项目,然后调用该接口,能正确返回当前配置环境的对应的form的值,就ok了!
同样的,我们可以把我们之前写在项目中的配置信息,直接放在git的配置文件中,项目会直接引用!本地无需配置!

 

(五) refresh

上面看到有个@RefreshScope,这个注解是用来做什么的?

首先我们先说下,refresh的引入:

1.pom中加入依赖(上面客户端的配置文件已经引入了该pom):


		
			org.springframework.boot
			spring-boot-starter-actuator
		
  • 注:增加了spring-boot-starter-actuator包,spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/refresh的功能。

2.添加注解,开启更新机制
给需要加载变量的类上,加上@RefreshScope

3.配置文件(上面客户端的bootstrap配置文件已经配置该配置参数):

#开启和暴露refresh端点,也可以  *  暴露所有端点
#在1.5.x版本中通过management.security.enabled=false来暴露所有端点
#在2.*版本后,通过此方式暴露指定端点
#注意在使用Http访问端点时,需要加上默认/actuator 前缀
management.endpoints.web.exposure.include=refresh

 

到这里,我们已经将refresh引入那我们我们思考一下

  • 我们更改了git上的form参数的值,再通过接口查询,值会改变吗?
  • 试一试后,我们会得出结论:并不会改变!

所以,在项目启动时,我们的项目就已经通过config-server服务获取到了在git上的配置信息,后面再修改git配置,也不会再主动的更新了。那么这不又回去了么....和本地配置文件有什么区别....
别慌!这就用到@RefreshScope了!

  • springcloud-config提供了@RefreshScope注解,当我们访问  http://127.0.0.1:7002/actuator/refresh时(注意,是post请求),就会去config-server服务中,重新拉去git上的配置信息!

 

注意!注意!注意!这里有坑!


我客户端的springboot版本2.0.0,springcloud版本Finchley.RELEASE,请求refresh的路径是:
http://127.0.0.1:7002/actuator/refresh

在这里我遇到一个问题,postman直接请求不会报错,但当用git的webhooks回调/refresh时,报了json反序列化错误:Cannot deserialize instance of `java.lang.String` out of START_OBJECT token错误,后来我将webhooks请求参数模拟放在postman内测试调用,发现也会出现相同问题,那么问题可能出在了当前版本上   (回调自己写的api是正常的)
后来我将springboot版本降级到1.5.6.RELEASE,springcloud版本Edgware.SR3,此时,refresh请求路径是:
http://127.0.0.1:7002/refresh
此时,问题解决了,不会再报上面的错误了!
所以就解决方式来看,应该是版本问题,导致解析json时发生了错误,至于为什么会产生这种原因,时间原因,我没有深究,如果你对此有了解,希望可以留言交流!
当然了,如果你一定希望自己的版本是2.0以上的,那么也可以解决,我看的一种方案是请求转发,可以参考这篇文章

 

(六) 关于refresh的思考

等等...,有点怪怪的(怪可爱的)。这种虽然可以通过主动调用的方式,进行更新配置

但难不成,我们更新一次git上的配置,就要再自己手动去调一下refresh接口?

这也太傻了!能不能我们一更新git,就可以自动重新让项目更新一下配置呢?

答案是...当然可以的!目前我了解的有种方式

  • 利用github之类的webhook,如果有修改就发起post请求/refresh就可以了,svn也有类似的hook机制,点击查看:https://blog.csdn.net/With_Her/article/details/99303803
  • 但是!当客户端越来越多的时候,需要每个客户端都执行一遍,这种方案就不太适合了。使用Spring Cloud Bus可以完美解决这一问题。这个我还没有看,了解之后再来总结一下!

(七)总结

到这里,关于springcloud-config的搭建与使用就完毕了!springcloud为我们提供了分布式中整个场景所遇到问题的解决方案,随着越来越深入的学习,果然发现其中的精妙之处!果然大厂子的大佬整出来的东西,就是厉害!

接下来,就是尝试将我们现有项目中的配置文件看能不能集成到springcloud-confg-server中去!

如果能帮助到你,我将感到十分荣幸!

当然,还有很多不足,如果你发现文章中有什么疑惑或问题,请及时留言交流!

参考文档:
https://blog.csdn.net/dyc87112/article/details/73739451
https://www.cnblogs.com/hellxz/p/9306507.html#commentform
https://blog.csdn.net/maoyeqiu/article/details/78543948#commentsedit
http://www.ityouknow.com/springcloud/2017/05/22/springcloud-config-git.html
http://www.ityouknow.com/springcloud/2017/05/23/springcloud-config-svn-refresh.html

转载请注明出处!

你可能感兴趣的:(框架,Git,JAVA,config-server)