SpringCloud系列之Config

作者 胡萝虎 日期 2018-04-28
SpringCloud系列之Config

相对于单体应用,微服务架构下的应用粒度小、部署实例的量级和复杂度大大增加。这时候,应用的配置如果还是和应用打包在一起部署,势必会造成维护和变更困难,难以支持业务的快速变化。因而,有必对配置进行集中化管理,以利于持续的维护。目前,比较成熟的集中式配置管理方案有几种,如Disconf、Diamond、Apollo,以及直接使用Zookeeper、Consul等中间件。在Spring Cloud技术栈中,官方为我们提供了一个新的选择:Spring Cloud Config。

准备

Spring Cloud Config由Config Server和Config Client组成,前者用于对配置数据进行管理,后者用于获取配置及处理配置变更。Config Server支持横向扩展,默认支持Git存储配置数据(也支持SVN和文件存储)。下面以Git作为存储方式来详细介绍。

Spring Cloud Config配置获取时序图

创建Git Repo

创建一个Git Repository,读者可以使用Github、Coding或自己搭建Gitlib等方式,很简单,这里就不再赘述。

准备配置文件

创建完Repository后,再创建config-example目录,如下图所示:

创建应用目录

然后再创建文件application-local.properties和application-test.properties,如下图

创建应用配置

application-local.preperties内容:

fooololo.host=local.huluohu.com
fooololo.username=local
fooololo.password=123

application-test.properties内容:

fooololo.host=test.huluohu.com
fooololo.username=test
fooololo.password=123

搭建ConfigServer

创建Maven工程

创建ConfigServer工程

添加依赖

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

创建启动类

package com.huluohu.cloud.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

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

添加应用配置

在src/main/resources目录下创建bootstrap.yml,内容如下

spring:
cloud:
config:
server:
bootstrap: true
git:
uri: https://github.com/fooololo/spring-cloud-config-repo
username: #git仓库的账号
password: #git仓库的密码
search-paths: '{application}' # 根据application的名称搜索目录

其中spring.cloud.config.server.git为上面创建的Git Repository的URL,username和password为你的Git账户名和密码。

在src/main/resources目录下创建application.yml,内容如下:

spring:
application:
name: config-server
server:
port: 8888

启动并测试Config Server

在浏览器中输入:http://localhost:8888/config-example/local/

返回的是config-example目录下application-local.properties配置文件中的内容

local环境配置

在浏览器中输入:http://localhost:8888/config-example/test/

返回的是config-example目录下application-testp.roperties配置文件中的内容

test环境配置

创建ConfigClient 应用

创建Maven工程

image-20180502141827430

添加依赖

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

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

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

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

创建启动类

package com.huluohu.cloud.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

添加应用配置

bootstarp

在src/main/resources目录下创建bootstrap.yml,内容如下

spring:
application:
name: config-example
cloud:
config:
uri: http://localhost:8888 # 配置服务器地址
fail-fast: true # 快速失败
name: ${spring.application.name} #默认就是spring.application.name
profile: ${spring.profiles.active:default} # 默认就是spring.profiles.active
label: master #标签
retry:
max-attempts: 6 #最大重试次数
max-interval: 2000 #间隔时间

spring.cloud.config.url配置的是上面我们搭建的Config Server的地址

其他参数默认可以不单独配置,其中重试和快速失败等配置不是必须的。

应用配置

在src/main/resources目录下创建application.yml,内容如下

server:
port: 8088

编写测试代码

编写一个controller,用来测试读取远程配置(也可以直接使用Junit进行测试),代码如下

package com.huluohu.cloud.config.web;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/test")
public class TestController {
//远程配置的key
@Value("${fooololo.host}")
private String host;

//远程配置的key
@Value("${fooololo.password}")
private String password;

//远程配置的key
@Value("${fooololo.username}")
private String userName;


@GetMapping("/config")
public ResponseEntity<Map<String, String>> testConfig() {
Map<String, String> map = new HashMap<>(3);
map.put("host", host);
map.put("userName", userName);
map.put("password", password);

return ResponseEntity.ok(map);
}
}
启动测试应用

image-20180502142744596

分别使用local和test profile启动应用,然后在浏览器中访问http://localhost:8088/test/config

image-20180502143131562

启动的时候可以看到应用会先从远处服务器拉取配置

local profile的结果

image-20180502143017837

test profile的结果

image-20180502143252735

刷新配置

应用发布上线以后,现在需要修改一个配置参数,例如将fooololo.password修改为456,这时候应该如何让修改生效呢?

增加依赖

在Config Client应用中增加以下依赖:

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

增加刷新注解

在TestController类上增加@RefreshScope注解,表示该类中使用@Value注解的配置项可能动态刷新

@RefreshScope
@RestController
@RequestMapping("/test")
public class TestController {
@Value("${fooololo.host}")
private String host;

@Value("${fooololo.password}")
private String password;

@Value("${fooololo.username}")
private String userName;


@GetMapping("/config")
public ResponseEntity<Map<String, String>> testConfig() {
Map<String, String> map = new HashMap<>(3);
map.put("host", host);
map.put("userName", userName);
map.put("password", password);

return ResponseEntity.ok(map);
}
}

修改配置

在application.yml中增加以下配置:

management:
security:
enabled: false

测试

  • 首先重启Config Client(以local profile为例)应用,即config-example,这时候访问http://localhost:8088/test/config获得password=123
  • 接着修改spring-cloud-config-repo仓库中config-example目录下application-local.properties中的fooololo.password=456
  • 然后使用Postman或其他工具,向http://localhost:8088/refresh发送一个POST请求
  • 最后再重新访问http://localhost:8088/test/config,可以看到password的值已经为456

Spring Cloud Config的简单配置已经介绍完了,在实际生产环境中,可能会需要更复杂的设置,读者可以在此基础上继续探索,找到适合自己的最佳实践!

你可能会喜欢

“扫一扫接着看”