spring boot 2.0.3+spring cloud (Finchley)6、配置中心Spring Cloud Config
https://www.cnblogs.com/cralor/p/9239976.html
Spring Cloud Config 是用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密 / 解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。Spring Cloud Config 实现了对服务端和客户端中环境变量和属性配置的抽象映射,所以它除了适用于 Spring 构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。由于 Spring Cloud Config 实现的配置中心默认采用 Git 来存储配置信息,所以使用 Spring Cloud Config 构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过 Git 客户端工具来方便的管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如:SVN 仓库、本地化文件系统。
Config Server从本地读取配置文件
本地仓库是指将所有的配置文件统一写在Config Server工程目录下。config server暴露Http API接口,config client通过调用config server的Http API接口来读取配置文件。
新建一个主maven项目,指定spring boot版本2.0.3,spring cloud版本 Finchley.RELEASE。

- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.cralor</groupId>
- <artifactId>chap10-config</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>chap10-config</name>
- <description>Demo project for Spring Boot</description>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.0.3.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <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</artifactId>
- </dependency>
- <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>
- </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>
- <!--使用aliyun镜像-->
- <repositories>
- <repository>
- <id>alimaven</id>
- <name>Maven Aliyun Mirror</name>
- <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
- <releases>
- <enabled>true</enabled>
- </releases>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>

构建Config Server
在主maven工程下,新建一个module工程config-server,pom文件继承主maven工程的pom文件,引入Config Server的起步依赖。

- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.cralor</groupId>
- <artifactId>config-server</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>config-server</name>
- <description>Demo project for Spring Boot</description>
- <parent>
- <groupId>com.cralor</groupId>
- <artifactId>chap10-config</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
- </properties>
- <dependencies>
- <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>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>

在启动类加上@EnableConfigServer注解

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

配置文件application.yml做相关配置:端口号8769,程序名config-server,spring.profiles.active=native来配置config server从本地读取配置读配置的路径为classpath下的shared目录。

- server:
- port: 8769
- spring:
- application:
- name: config-server
- profiles:
- active: native
- cloud:
- config:
- server:
- native:
- search-locations: classpath:/shared

在gcresources目录下新建shared文件夹,存放配置文件,新建文件config-client-dev.yml,用作eureka-client工程的dev(开发环境)的配置文件。在config-client-dev.yml配置文件中,指定端口号8762,定义一个变量foo,值为foo version 1。
- server:
- port: 8762
- foo: foo version 1
构建Config Client
新建工程config-client,该工程作为Config Client从Config Server读取配置文件,pom文件继承主maven工程的pom文件,引入Config的起步依赖,web的起步依赖(已在主maven工程pom中配置)。
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-config</artifactId>
- </dependency>
在配置文件bootstrap.yml中做相关配置。注意,这些与 Spring Cloud Config 相关的属性必须配置在 bootstrap.yml 中,config 部分内容才能被正确加载,因为 config 的相关配置会先于 application.yml,而 bootstrap.yml 的加载也是先于 application.yml。指定程序名config-client,向Url地址为http://localhost:8769的Config Server读取配置文件。如果没有读取成功则执行快速失败(fail-fast),读取的是dev文件。配置文件中的变量{spring.application.name}和{spring.profiles.active},两者以 “-” 相连,构成了向Config Server读取的配置文件名,config-client-dev.yml。

- spring:
- application:
- name: config-client
- profiles:
- active: dev
- cloud:
- config:
- uri: http://localhost:8769
- fail-fast: true

在config-client工程写一个API测试接口,读取配置文件的foo变量并返回。

- @RestController
- public class MyController {
- @Value("${foo}")
- String foo;
- @RequestMapping("/foo")
- public String hi(){
- return foo;
- }
- }

启动工程config-server,再启动config-client,此时控制台会显示config-client向Url地址为http://localhost:8769的Config Server读取了配置文件,程序的启动端口为8762。
浏览器访问http://localhost:8762/foo,显示
可见,config client成功向config server读取了配置文件。
Config Server从远程Git仓库读取配置文件
Config Server从远程Git仓库读取配置文件,可以将配置统一管理,并且可以通过Spring Cloud Bus在不人工启动程序的情况下对Config Client的配置进行刷新。本例采用的是GitHub作为远程Git仓库。
修改Config Server的配置文件application.yml。

- server:
- port: 8769
- spring:
- application:
- name: config-server
- cloud:
- config:
- server:
- git:
- uri: https://github.com/cralor7/springcloud
- search-paths: config-repo
- # username:
- # password:
- default-label: master

uri为GitHub仓库的地址,search-paths为远程仓库中配置文件所在路径,username和password为GitHub仓库的登录名和密码,如果是私有的仓库登录名和密码是必须的,公开的仓库可以不需要,default-label为仓库的分支,本例是从master读取。
将config-client-dev.yml稍作修改,上传到GitHub仓库中,
依次重启config-server,config-client,控制台
浏览器访问http://localhost:8763/foo
可见,config-server从远程仓库读取了配置文件,config-client从config-sever读取了配置文件。
构建高可用的Config Server
当服务实例很多时,所有的服务实例需要同时从配置中心Config Server读取配置文件,这时可以考虑将配置中心Config Server做成一个微服务,并且将其集群化,从而达到高可用。Config Server和Config Client向Eureka Server注册,且将Config Server多实例部署。
构建Eureka Server
新建eureka-server工程,pom文件继承主maven的pom文件引入Eureka Server和web的起步依赖。
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
- </dependency>
配置文件application.yml做相关配置,指定端口号8761,并不自注册(将register-with-eureka和fetch-registry设置为false)。

- server:
- port: 8761
- eureka:
- instance:
- hostname: localhost
- client:
- register-with-eureka: false
- fetch-registry: false
- serviceUrl:
- defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动类加注解@EnableEurekaServer

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

改造Config Server
作为Eureka Client需要在pom文件引入Eureka Client的起步依赖
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
在配置文件application.yml指定注册服务注册的地址

- server:
- port: 8769
- spring:
- application:
- name: config-server
- cloud:
- config:
- server:
- git:
- uri: https://github.com/cralor7/springcloud
- search-paths: config-repo
- # username:
- # password:
- default-label: master
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/

改造Config Client
和Config Server一样加入Eureka Client的起步依赖,配置文件bootstrap.yml中,指定注册服务注册的地址http://localhost:8761/eureka/,向service-id为config-server的配置服务读取配置文件。

- spring:
- application:
- name: config-client
- profiles:
- active: dev
- cloud:
- config:
- fail-fast: true
- discovery:
- enabled: true
- service-id: config-server
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/

依次启动eureka-server和config-server(config-server开启两个实例,端口号8768、8769),成功后启动config-client。通过控制台可以看到config-client向地址为http://localhost:8768的config-server读取了配置文件,浏览器访问http://localhost:8763/foo,显示
多次启动config-client工程(我测试的时候重启了4、5次),控制台可以看到它会轮流从http://localhost:8768和http://localhost:8769的Config Server读取配置文件,并做了负载均衡。
使用Spring Cloud Bus刷新配置
Spring Cloud Bus 通过轻量消息代理连接各个分布的节点,可以用于广播配置文件的更改或者服务的监控管理。一个关键的思想就是,消息总线可以为微服务做监控,也可以实现应用程序之间相互通信。Spring Cloud Bus可选的消息代理组件包括RabbitMQ和Kafka等。这里用RabbitMQ作为Spring Cloud的消息组件去刷新更改微服务的配置文件。
为什么用Spring Cloud Bus去刷新配置呢?
如果有几十个微服务,而每一个服务优势多实例,当更改配置时,需要重启多个微服务实例。Spring Cloud Bus的一个功能就是让这个过程变得简单,当远程Git仓库的配置文件更改后,只需要向某一个微服务实例发送一个Post请求,通过消息组件通知其他微服务实例重新去仓库拉取最新的配置文件。
由于使用了RabbitMQ,首先必需安装RabbitMQ。此处略...,(我安装时去官网下载了最新的Erlang和RabbitMQ,结果杯具了...,安装RabbitMQ时,Erlang的环境变量已经配置成功了结果还提示 ERLANG_HOME 找不到,原来Erlang和RabbitMQ还有版本匹配问题,从OTP 21.0一直到OTP 19.3,才终于可以了。附下载地址:Erlang,rabbRabbitMQ)
改造config-server
pom文件添加依赖,这 4 个是必须的,

- <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>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-bus</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
- </dependency>

配置文件application.yml

- server:
- port: 8769
- spring:
- application:
- name: config-server
- cloud:
- config:
- server:
- git:
- uri: https://github.com/cralor7/springcloud
- search-paths: config-repo
- # username:
- # password:
- default-label: master
- bus:
- trace:
- enabled: true
- enabled: true
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/
- management:
- endpoints:
- web:
- exposure:
- include: bus-refresh

改造config-client
pom文件,这5个是必需的,还要加上web的起步依赖(已在主maven工程pom中配置)

- <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>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-bus</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>

配置文件bootstrap.yml

- server:
- port: 8763
- spring:
- application:
- name: config-client
- profiles:
- active: test
- cloud:
- config:
- fail-fast: true
- discovery:
- enabled: true
- service-id: config-server
- bus:
- trace:
- enabled: true
- enabled: true
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/

在需要更新的配置类上加@RefreshScope注解,@RefreshScope必须加,否则客户端会收到服务端的更新消息,但是更新不了,因为不知道更新哪里的。

- @RefreshScope
- @RestController
- public class MyController {
- @Value("${foo}")
- String foo;
- @RequestMapping("/foo")
- public String hi(){
- return foo;
- }
- }

依次启动eureka-server、config-server和config-client(config-client开启两个实例,端口号8762、8763),访问浏览器http://localhost:8762/foo和http://localhost:8763/foo,显示
更改远程仓库配置文件,将foo的值改为”foo: foo version 7“。通过Postman或其他工具发送一个Post请求http://localhost:8769/actuator/bus-refresh/,请求发送成功后,再访问浏览器,显示
可见,通过向8769端口的服务端发送Post请求刷新配置,由于使用了Spring Cloud Bus,其他服务实例(如两个客户端)也会接收到刷新配置的消息,并刷新配置。
对客户端config-client使用 /actuator/bus-refresh。
首先需要把config-client上的bus-refresh
端点给放出来,更改config-client的配置文件。发送Post请求http://localhost:8762/actuator/bus-refresh/。

- server:
- port: 8763
- spring:
- application:
- name: config-client
- profiles:
- active: test
- cloud:
- config:
- fail-fast: true
- discovery:
- enabled: true
- service-id: config-server
- bus:
- trace:
- enabled: true
- enabled: true
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/
- management:
- endpoints:
- web:
- exposure:
- include: bus-refresh

测试后可见8762、8763端口客户端都发生了改变。说明只要开启 Spring Cloud Bus 后,不管是对 config-server 还是 config-client 执行/actuator/bus-refresh
都是可以更新配置的。
局部刷新
某些场景下(例如灰度发布),我们可能只想刷新部分微服务的配置,此时可通过/actuator/bus-refresh/{destination}
端点的 destination 参数来定位要刷新的应用程序。例如:/actuator/bus-refresh/customers:8000
,这样消息总线上的微服务实例就会根据 destination 参数的值来判断是否需要要刷新。其中,customers:8000
指的是各个微服务的 ApplicationContext ID。destination 参数也可以用来定位特定的微服务。例如:/actuator/bus-refresh/customers:**
,这样就可以触发 customers 微服务所有实例的配置刷新。
参考:Spring Cloud(九):配置中心(消息总线)【Finchley 版】
案例代码地址:https://github.com/cralor7/springcloud
spring boot 2.0.3+spring cloud (Finchley)6、配置中心Spring Cloud Config的更多相关文章
- Quick Guide to Microservices with Spring Boot 2.0, Eureka and Spring Cloud
https://piotrminkowski.wordpress.com/2018/04/26/quick-guide-to-microservices-with-spring-boot-2-0-eu ...
- Spring Boot 2.0正式发布,新特性解读
作者|翟永超 Spring Boot 2.0 来啦,有哪些新特性?升级吗? 写在前面 北京时间 3 月 1 日,经过漫长的等待之后,Spring Boot 2.0 正式发布.作为 Spring 生态中 ...
- 重磅:Spring Boot 2.0 正式发布!
Spring Boot 2.0 正式发布! 2018/03/01最新消息,传得沸沸扬扬的Spring Boot 2.0 正式发布了. 小编去看了下Spring Boot的官网,正式版本已经释放出来了! ...
- Spring Boot 2.0 返回JSP页面实战
1. 模板引擎JSP的限制 在开始之前呢,我觉得我们有必要先去了解下 Spring Boot 2.0 官方文档中提到的如下内容: 模板引擎 除了REST Web服务之外,还可以使用Spring MVC ...
- Spring Boot 2.0系列文章(五):Spring Boot 2.0 项目源码结构预览
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/04/15/springboot2_code/ 项目结构 结构分析: Spring-boot-pr ...
- Spring Boot 2.0系列文章(七):SpringApplication 深入探索
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/04/30/springboot_SpringApplication/ 前言 在 Spring B ...
- Spring Boot 2.0 升级指南
Spring Boot 2.0 升级指南 前言 Spring Boot已经发布2.0有5个月多,多了很多新特性,一些坑也慢慢被填上,最近有空,就把项目中Spring Boot 版本做了升级,顺便整理下 ...
- spring boot 2.0 源码分析(一)
在学习spring boot 2.0源码之前,我们先利用spring initializr快速地创建一个基本的简单的示例: 1.先从创建示例中的main函数开始读起: package com.exam ...
- Spring Boot 2.0 迁移指南

公司用来测试的服务器挂了,最后重装了系统,需要重新配置程序运行环境,linux上安装不是很熟悉,特此记录一下. 首先获取系统版本信息: 参考:获取Linux系统版本信息 一.mysql 1. 安装 安 ...
- 【Python】HackBack(获取暴力破解服务器密码的IP来源)
1.前言 又在0x00sec上翻到好东东. https://0x00sec.org/t/python-hackback-updated/882 帖子里的脚本会得到那些暴力服务器密码失败的IP和用户名, ...
- linux通过sendmail发送邮件
安装sendmail: [root@li676-235 ~]# yum install sendmail 安装好后执行. [root@li676-235 ~]# /etc/init.d/sendmai ...