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

3 篇文章 0 订阅
3 篇文章 0 订阅

前言:

公司的所有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如下:

        <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.configserver</groupId>
	<artifactId>configserver</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>configserver</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

需要注意的是:之前我们一般都是用的各种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如下图所示:

到这一步,我们的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调用一下,会返回相应的结果:

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

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

 

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

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

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

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

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

    <modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.getconfiginfo</groupId>
	<artifactId>get-configinfo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>get-configinfo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<!--Spring Boot Actuator,感应服务端变化-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

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):

<!--Spring Boot Actuator,感应服务端变化-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
  • 注:增加了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

转载请注明出处!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值