5.配置中心

项目中一般都会有一些配置文件,例如数据库连接配置、redis连接信息等。在传统的项目中,通常将配置文件与源码放在一起打包部署到服务器上。但是在微服务架构中,,采用这种方式就会存在一些问题。为了保证服务的高可用,通常针对每一个服务都会启动多个实例,提供服务,通过负载均衡机制来将请求转发到多个实例中的一个上。如果需要修改配置文件,就需要将这个服务的所有的实例的配置文件都进行修改,一般每个实例都会部署在不同的机器上,这样挨个去修改配置文件会及其繁琐。springcloud提供了配置中心可以简化这个操作。我们可以将配置文件存储到远端仓库中(一般使用git或者svn作为远端仓库),然后同一个微服务的多个实例都从远端仓库读取同一份配置文件,这样在修改时,也只需要修改一次就可以了。

下面来介绍一下基于git来实现的配置中心。

服务端

准备工作:

先创建如下三个配置文件,然后在GitHub上创建一个仓库,将创建的配置文件上传的仓库。
在这里插入图片描述
这三个配置文件中的内容分别如下:

config-dev.properties:

hello=dev
desc=this is a dev config

config-pro.properties:

hello=pro

config-test.properties:

hello=test

创建一个springboot作为配置中心服务端,引入以下pom依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

在该项目的启动类上添加@EnableConfigServer注解,就可以将该项目作为一个服务中心服务。

修改application.properties文件,添加以下配置:

spring.application.name=config-server
server.port=7001
# git配置信息
# 配置git仓库位置
spring.cloud.config.server.git.uri=https://github.com/xxxxgithub/springcloud-config-demo
# 配置仓库路径下的相对搜索位置,可以配置多个,英文逗号分隔
spring.cloud.config.server.git.searchPaths=
# 访问git仓库的用户名
spring.cloud.config.server.git.username=git仓库用户名
# 访问git仓库的用户名密码
spring.cloud.config.server.git.password=git仓库密码

然后启动项目,测试一下在server端是否能够读取到GitHub仓库中的配置文件的内容,在浏览器地址栏直接访问http://localhost:7001/config/dev,可以看到如下信息:

{
	"name": "config",
	"profiles": ["dev"],
	"label": null,
	"version": "82feae0a7c71b7e95e0a71e7b21b9f19d8254a79",
	"state": null,
	"propertySources": [{
		"name": "https://github.com/xxxxgithub/springcloud-config-demo/config-dev.properties",
		"source": {
			"hello": "dev"
		}
	}]
}

这些信息包含了配置文件的位置、名称、版本以及具体内容等。至此说明在服务端已经能够读取到GitHub仓库中的配置文件了。

从上面访问的那个URL中可以看出,spring对我们创建的配置文件的文件名进行了解析,然后生成了那个URL,那么spring是按照什么规则解析文件名并且拼装成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分支。

在config-dev.properties配置文件中新增一行:

desc=this is a dev config

将改动push到git仓库,再次访问http://localhost:7001/config/dev :

{
	"name": "config",
	"profiles": ["dev"],
	"label": null,
	"version": "b95700ff5ee3adabd2d952ab543088bae7c2379f",
	"state": null,
	"propertySources": [{
		"name": "https://github.com/xxxxgithub/springcloud-config-demo/config-dev.properties",
		"source": {
			"hello": "dev",
			"desc": "this is a dev config"
		}
	}]
}

可以看到,server端已经能从git仓库中读取到最新的配置文件的内容了。

在客户端获取配置文件内容

创建一个新的springboot项目作为客户端去从server端获取配置文件的内容。

在项目的pom文件中增加依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

创建bootstrap.properties文件:

spring.application.name=config
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:7001/
spring.cloud.config.label=master
# spring.cloud.config.discovery.service-id= 指定配置中心的service-id,便于扩展为高可用配置集群
server.port=9005

注意:上面说过,springcloud-config会按照{application}-{profile}.properties的格式去解析配置文件的文件名。这里的spring.application.name配置值一定要与配置文件的{application}部分保持一致。

另外还需要注意一下bootstrap.properties与application.properties文件的加载顺序和优先级。

项目启动时会先加载bootstrap.properties文件。

创建一个controller,模拟在client中获取配置:

@RestController
public class SpringCloudConfigClientController {
	
	@Value("${hello}")
	private String hello;
	
	@Value("${desc}")
	private String description;
	
	@RequestMapping("hello-config")
	public String helloConfig() {
		return hello + ":" + description;
	}

}

client的启动类使用默认生成的就好,不需要改变,如下:

@SpringBootApplication
public class SpringcloudConfigclientApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringcloudConfigclientApplication.class, args);
	}

}

先启动server,然后启动client,访问:http://localhost:9005/hello-config,就可以看到页面上显示了配置信息:
在这里插入图片描述

refresh

接着上一节,我们继续来做个测试,首先在本地将config-dev.properties文件中的配置修改一下,如下:

hello=dev
desc=this is a dev config update aaaa

然后将修改push到git仓库,访问config-server:http://localhost:7001/config/dev,页面上的响应内容如下:

{
	"name": "config",
	"profiles": ["dev"],
	"label": null,
	"version": "0d87394cd708673c6e947f252a368eae5a1cc266",
	"state": null,
	"propertySources": [{
		"name": "https://github.com/xxxxgithub/springcloud-config-demo/config-dev.properties",
		"source": {
			"hello": "dev",
			"desc": "this is a dev config update aaaa"
		}
	}]
}

可以看到,配置中心读取到的配置文件内容已经是修改过的,说明配置中心可以实时读取到仓库中最新的配置信息,接着我们访问以下config-client:http://localhost:9005/hello-config,页面显示如下:
在这里插入图片描述
发现客户端却不能读取到修改后的文件内容,为什么呢?

spring cloud config 分为服务端和客户端,服务端的作用是将git中存储的配置文件发布为TEST接口,客户端通过调用服务端的REST接口获取配置,但是客户端并不能主动感知到配置文件的变化,从而去获取新的配置信息。针对这一问题,spring cloud config 提供了解决方案,每个客户单通过POST方法触发各自的/refresh。

修改客户端的pom,增加以下依赖:

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

在客户端的controller类上增加@RefreshScope注解:

@RefreshScope
@RestController
public class SpringCloudConfigClientController {
	
	@Value("${hello}")
	private String hello;
	
	@Value("${desc}")
	private String description;
	
	@RequestMapping("hello-config")
	public String helloConfig() {
		return hello + ":" + description;
	}

}

在客户端的bootstrap.properties文件中增加以下配置:

management.endpoints.web.exposure.include=refresh

注意这里springboot1.x跟springboot2.x不一样。

然后启动客户端,使用postman发送POST请求:http://localhost:9005/actuator/refresh,得到如下响应信息:

[
    "config.client.version",
    "desc"
]

然后再到浏览器中发送http://localhost:9005/hello-config请求,发现页面上已经是修改过后的配置信息了:
在这里插入图片描述
至此,我们已经搭建起了一个配置中心,并且能够在客户端拿到实时更新的配置信息了。

**注意:**配置中心也可以做高可用,启动多个实例并注册到服务注册中心。本文只是单独介绍配置中心server和配置中心client的用法,并没有将server注册到服务在注册中心,如果需要可自行查阅配置方法。

最后本文还遗留一个问题,每次修改git仓库的配置文件后都要手动发一个POST请求refresh,有点麻烦,能不能有一种方法可以在git仓库中的配置文件变化后,自动发送refresh请求呢?

这里可以利用GitHub网站的的webhook功能,这里先不介绍,留着以后再说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值