Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密 / 解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。Spring Cloud Config 实现了对服务端和客户端中环境变量和属性配置的抽象映射,所以它除了适用于 Spring 构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。由于 Spring Cloud Config 实现的配置中心默认采用 Git 来存储配置信息,所以使用 Spring Cloud Config 构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过 Git 客户端工具来方便的管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如:GIT仓库、SVN 仓库、本地化文件系统。

下面我们将构建一个基于 Git 存储的分布式配置中心,并对客户端进行改造,让其能够从配置中心获取配置信息并绑定到代码中。

准备工作

准备一个 Git 仓库,在 Github 上面创建了一个文件夹 config-repo 用来存放配置文件,为了模拟生产环境,我们创建以下三个配置文件:

 // 开发环境
config-server-dev.yml
// 测试环境
config-server-test.yml
// 生产环境
config-server-prod.yml

每个配置文件中都写一个属性 info.profile, 属性值分别是 dev/test/prod

Server 端

创建一个基础的 Spring Boot 工程,命名为:service-config-server

POM依赖

 <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置文件

在 application.yml 中添加配置服务的基本信息以及 Git 仓库的相关信息

server:
port: 9300
spring:
application:
name: service-config-server
cloud:
config:
server:
git:
uri: https://github.com/carry-chan/spring-cloud # 配置git仓库的地址
search-paths: config-repo # git仓库地址下的相对地址,可以配置多个,用,分割。
eureka:
client:
serviceUrl:
defaultZone: http://admin:123456@localhost:8761/eureka/

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

如果我们的 Git 仓库需要权限访问,那么可以通过配置下面的两个属性来实现
spring.cloud.config.server.git.username:访问 Git 仓库的用户名
spring.cloud.config.server.git.password:访问 Git 仓库的用户密码

启动类

 package com.carry.springcloud;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer; @EnableConfigServer
@SpringBootApplication
public class ServiceConfigServerApplication { public static void main(String[] args) {
SpringApplication.run(ServiceConfigServerApplication.class, args);
}
}

到此 Server 端相关配置已经完成。

测试

启动eureka-server、service-config-server,浏览器直接访问 http://localhost:9300/config-server/dev 返回信息如下:

{
"name": "config-server",
"profiles": [
"dev"
],
"label": null,
"version": "beb220098b44c60cf99277f064a19d52e7ebeb91",
"state": null,
"propertySources": [
{
"name": "https://github.com/carry-chan/spring-cloud/config-repo/config-server-dev.yml",
"source": {
"info.profile": "dev"
}
}
]
}

上述的返回的信息包含了配置文件的位置、版本、配置文件的名称以及配置文件中的具体内容,说明 Server 端已经成功获取了 Git 仓库的配置信息。

如果直接查看配置文件中的配置信息可访问 http://localhost:9300/config-server-dev.yml 返回:

info:
profile: dev

修改配置文件config-server-dev.yml中配置信息为dev v0,再次在浏览器访问 http://localhost:9300/config-server-dev.yml 返回:dev v0,说明 Server 端会自动读取最新提交的内容。

仓库中的配置文件会被转换成 Web 接口,访问可以参照以下的规则:

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

上面的 URL 会映射 {application}-{profile}.yml 对应的配置文件,其中 {label} 对应 Git 上不同的分支,默认为 master。

Client 端

创建一个基础的 Spring Boot 应用,命名为 service-config-client。

POM依赖

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置文件

需要配置两个配置文件,application.yml 和 bootstrap.yml,配置分别如下:

application.yml

server:
port: 9400
spring:
application:
name: service-config-client

bootstrap.yml

spring:
cloud:
config:
name: config-server # 对应 {application} 部分
profile: dev # 对应 {profile} 部分
label: master # 对应 {label} 部分,即 Git 的分支。如果配置中心使用的是本地存储,则该参数无用
discovery:
enabled: true
service-id: service-config-server #springcloud config的服务名
eureka:
client:
serviceUrl:
defaultZone: http://admin:123456@localhost:8761/eureka/

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

启动类

 package com.carry.springcloud;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class ServiceConfigClientApplication { public static void main(String[] args) {
SpringApplication.run(ServiceConfigClientApplication.class, args);
}
}

在 Controller 中使用 @Value 注解来获取 Server 端参数的值

 package com.carry.springcloud;

 import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController
public class ClientController { @Value("${info.profile}")
private String profile; @GetMapping("/info")
public Mono<String> hello() {
return Mono.justOrEmpty(profile);
}
}

测试

依次启动项目eureka-server、service-config-server、service-config-client,访问 http://localhost:9400/info 返回dev 说明已经正确的从 Server 端获取到了参数。

手动修改Git仓库中 config-server-dev.yml 的值,再次访问 http://localhost:9400/info 依旧返回dev,这是因为 Spring Cloud Config 分服务端和客户端,服务端负责将 Git 中存储的配置文件发布成 REST 接口,客户端可以从服务端 REST 接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置。客户端如何去主动获取新的配置信息呢,Spring Cloud 已经给我们提供了解决方案,每个客户端通过 POST 方法触发各自的 /actuator/refresh。

Refresh功能

修改客户端即 service-config-client 项目

添加依赖

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

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

开启更新机制

需要给加载变量的类上面加 @RefreshScope,在客户端执行/actuator/refresh的时候就会更新此类下面的变量值。

 package com.carry.springcloud;

 import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController
@RefreshScope
public class ClientController { @Value("${info.profile}")
private String profile; @GetMapping("/info")
public Mono<String> hello() {
return Mono.justOrEmpty(profile);
}
}

配置

Spring Boot 1.5.X 以上默认开通了安全认证,所以要在配置文件 application.yml 中添加以下配置以将/actuator/refresh这个 Endpoint 暴露出来

management:
endpoints:
web:
exposure:
include: refresh

测试

重启 service-config-client 项目

访问 http://localhost:9400/info 返回dev

我将 Git 上对应配置文件里的值改为dev v0

执行 curl -X POST http://localhost:9400/actuator/refresh,返回["config.client.version","info.profile"]

再次访问 http://localhost:9400/info 返回dev v0

这就说明客户端已经得到了最新的值,Refresh 是有效的。

Webhook

现在虽然可以不用重启服务就更新配置了,但还是需要我们手动操作,这样还是不可取的。所以,这里就要用到git的webhooks来达到自动更新配置。

打开git上配置仓库的地址,添加webhooks

上面的Payload URL就填写我们的配置中心触发刷新的地址,当然这里不能写localhost,要外网访问地址才行。还有这里面有个Secret的秘钥验证,如果这里填写的话,在配置文件上要写上encrypt.key与之对应。

Spring Cloud学习笔记【九】配置中心Spring Cloud Config的更多相关文章

  1. Spring框架学习笔记(5)——Spring Boot创建与使用

    Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...

  2. Spring框架学习笔记(8)——spring boot+mybatis plus+mysql项目环境搭建

    之前写的那篇Spring框架学习笔记(5)--Spring Boot创建与使用,发现有多小细节没有提及,,正好现在又学习了mybatis plus这款框架,打算重新整理一遍,并将细节说清楚 1.通过I ...

  3. 【Spring Cloud学习之五】配置中心

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 一.什么是配置中心在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实 ...

  4. Spring框架学习笔记(7)——Spring Boot 实现上传和下载

    最近忙着都没时间写博客了,做了个项目,实现了下载功能,没用到上传,写这篇文章也是顺便参考学习了如何实现上传,上传和下载做一篇笔记吧 下载 主要有下面的两种方式: 通过ResponseEntity实现 ...

  5. spring实战学习笔记(一)spring装配bean

    最近在学习spring boot 发现对某些注解不是很深入的了解.看技术书给出的实例 会很疑惑为什么要用这个注解? 这个注解的作用?有其他相同作用的注解吗?这个注解的运行机制是什么?等等 spring ...

  6. SpringMVC + Spring + MyBatis 学习笔记:SpringMVC和Spring一同工作的时候,AOP事务管理不起作用的解决方法

    系统:WIN8.1 数据库:Oracle 11GR2 开发工具:MyEclipse 8.6 框架:Spring3.2.9.SpringMVC3.2.9.MyBatis3.2.8 SpringMVC 的 ...

  7. Spring框架学习笔记(10)——Spring中的事务管理

    什么是事务 举例:A给B转500,两个动作,A的账户少500,B的账户多500 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 一.注解添加事务管理方 ...

  8. Spring框架学习笔记(9)——Spring对JDBC的支持

    一.使用JdbcTemplate和JdbcDaoSupport 1.配置并连接数据库 ①创建项目并添加jar包,要比之前Spring项目多添加两个jar包c3p0-0.9.1.2.jar和mysql- ...

  9. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

  10. Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config

    目录 Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config Spring Cloud Config(二):基于Git搭建配置中心 Spring Cl ...

随机推荐

  1. php 生成 guid

    function guid( $opt = true ){ // Set to true/false as your default way to do this. if( function_exis ...

  2. 【原创】关于JMS[1]

    面向消息中间件(MOM)为分布式系统提供异步,解耦,稳定,可扩展和安全的行为.MOM在分布式计算领域是一个重要的概念.它允许应用使用代理器API在分布式环境实现各种功能.Java消息服务(Java M ...

  3. 设置IE浏览器文档模式版本

    浏览器版本问题是所有开发web的程序员共同的诟病,尤其是IE浏览器,笔者上次修改公司的一个项目中出现项目是在IE9没有出来之前,而现在修改时,则发现页面上出现的表格的错乱(因为表格是通过js动态生成的 ...

  4. shell简单监控脚本模板

    #!/bin/bash host=127.0.0.1user=adminpassword='xx'port=6032x=0check_proxy(){v=$(mysql -N -u$user -p$p ...

  5. rman参数

    rman 参数 RMAN> show all; 参数是存放在控制文件中的 改参数:(直接改) eg: CONFIGURE RETENTION POLICY TO REDUNDANCY 3 参数: ...

  6. 3ds Max怎么制作亮木材质的球体

    3DSMax怎么制作亮木材质的球体?3DSMax中想要设计一款亮木材质的球体,该怎么设置呢?下面我们就来看看详细的教程,需要的朋友可以参考下! 1.运行软件,选择材质编辑器图标: 3.双击拖拽出的材质 ...

  7. mongodb报错:connection refused because too many open connections: 819

    问题: 发现mongodb无法连接,查看mongodb日志,出现大量的如下报错: [initandlisten] connection refused because too many open co ...

  8. 安装lnmp前请先运行screen

    当通过putty或者SecureCRT安装lnmp时, 网络突然掉线或者不小心putty被关掉等等原因, 造成lnmp安装过程被中断怎么办? 其实防止这种现象很简单, 只要在安装lnmp前执行scre ...

  9. webpack中optimization 的 runtimeChunk 是干嘛的

    结论:把runtime部分的代码抽离出来单独打包 https://developers.google.com/web/fundamentals/performance/webpack/use-long ...

  10. 【BZOJ 1588】 [HNOI2002]营业额统计

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每天的最小波动值指的是和之前所有天的差值的绝对值中的最小值. 用set.的lower_bound函数. 每次找和他差值最小的数字就好 ...